},
{
"path": "./dist/css/bootstrap.css",
- "maxSize": "36.5 kB"
+ "maxSize": "37.5 kB"
},
{
"path": "./dist/css/bootstrap.min.css",
- "maxSize": "33.0 kB"
+ "maxSize": "33.75 kB"
},
{
"path": "./dist/js/bootstrap.bundle.js",
// 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-color: var(--#{$prefix}color-body) !default;
+$accordion-bg: var(--#{$prefix}bg-body) !default;
$accordion-border-width: var(--#{$prefix}border-width) !default;
$accordion-border-color: var(--#{$prefix}border-color) !default;
$accordion-border-radius: var(--#{$prefix}border-radius-lg) !default;
@layer components {
.alert {
// scss-docs-start alert-css-vars
- --#{$prefix}alert-bg: transparent;
+ --#{$prefix}alert-bg: var(--#{$prefix}theme-bg-subtle, transparent);
--#{$prefix}alert-padding-x: #{$alert-padding-x};
--#{$prefix}alert-padding-y: #{$alert-padding-y};
--#{$prefix}alert-margin-bottom: #{$alert-margin-bottom};
- --#{$prefix}alert-color: inherit;
+ --#{$prefix}alert-color: var(--#{$prefix}theme-text, inherit);
--#{$prefix}alert-border-color: transparent;
- --#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color);
+ --#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}theme-border, var(--#{$prefix}alert-border-color));
--#{$prefix}alert-border-radius: #{$alert-border-radius};
--#{$prefix}alert-link-color: inherit;
// scss-docs-end alert-css-vars
position: relative;
padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x);
- margin-bottom: var(--#{$prefix}alert-margin-bottom);
+ // margin-bottom: var(--#{$prefix}alert-margin-bottom);
color: var(--#{$prefix}alert-color);
background-color: var(--#{$prefix}alert-bg);
border: var(--#{$prefix}alert-border);
// scss-docs-start alert-modifiers
// Generate contextual modifier classes for colorizing the alert
- @each $state in map.keys($new-theme-colors) {
- .alert-#{$state} {
- --#{$prefix}alert-color: var(--#{$prefix}#{$state}-text);
- --#{$prefix}alert-bg: var(--#{$prefix}#{$state}-bg-subtle);
- --#{$prefix}alert-border-color: var(--#{$prefix}#{$state}-border-subtle);
- --#{$prefix}alert-link-color: var(--#{$prefix}#{$state}-text-emphasis);
- }
- }
+ // @each $state in map.keys($new-theme-colors) {
+ // .alert-#{$state} {
+ // --#{$prefix}alert-color: var(--#{$prefix}#{$state}-text);
+ // --#{$prefix}alert-bg: var(--#{$prefix}#{$state}-bg-subtle);
+ // --#{$prefix}alert-border-color: var(--#{$prefix}#{$state}-border-subtle);
+ // --#{$prefix}alert-link-color: var(--#{$prefix}#{$state}-text-emphasis);
+ // }
+ // }
// scss-docs-end alert-modifiers
}
@use "config" as *;
@use "colors" as *;
@use "variables" as *;
+@use "theme" as *;
@use "mixins/border-radius" as *;
@use "mixins/gradients" as *;
@use "vendor/rfs" as *;
// scss-docs-start badge-variables
$badge-font-size: .75em !default;
$badge-font-weight: $font-weight-bold !default;
-$badge-color: $white !default;
+$badge-color: inherit !default;
$badge-padding-y: .35em !default;
-$badge-padding-x: .65em !default;
+$badge-padding-x: .5em !default;
$badge-border-radius: var(--#{$prefix}border-radius) !default;
// scss-docs-end badge-variables
--#{$prefix}badge-padding-y: #{$badge-padding-y};
@include rfs($badge-font-size, --#{$prefix}badge-font-size);
--#{$prefix}badge-font-weight: #{$badge-font-weight};
- --#{$prefix}badge-color: #{$badge-color};
+ --#{$prefix}badge-color: var(--#{$prefix}theme-contrast, #{$badge-color});
+ --#{$prefix}badge-bg: var(--#{$prefix}theme-bg, var(--#{$prefix}bg-2));
--#{$prefix}badge-border-radius: #{$badge-border-radius};
// scss-docs-end badge-css-vars
text-align: center;
white-space: nowrap;
vertical-align: baseline;
+ background-color: var(--#{$prefix}badge-bg);
@include border-radius(var(--#{$prefix}badge-border-radius));
@include gradient-bg();
position: relative;
top: -1px;
}
+
+ .badge-subtle {
+ --#{$prefix}badge-color: var(--#{$prefix}theme-text);
+ --#{$prefix}badge-bg: var(--#{$prefix}theme-bg-subtle);
+ }
}
$card-cap-color: null !default;
$card-height: null !default;
$card-color: null !default;
-$card-bg: var(--#{$prefix}body-bg) !default;
+$card-bg: var(--#{$prefix}bg-body) !default;
$card-img-overlay-padding: $spacer !default;
$card-group-margin: $grid-gutter-width * .5 !default;
// scss-docs-end card-variables
flex-direction: column;
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
height: var(--#{$prefix}card-height);
- color: var(--#{$prefix}body-color);
+ color: var(--#{$prefix}color-body);
word-wrap: break-word;
background-color: var(--#{$prefix}card-bg);
background-clip: border-box;
:root {
@each $color, $hue in $hues {
- --#{$prefix}#{$color}-025: color-mix(in srgb, #fff 94%, #{$hue});
- --#{$prefix}#{$color}-050: color-mix(in srgb, #fff 90%, #{$hue});
- --#{$prefix}#{$color}-100: color-mix(in srgb, #fff 80%, #{$hue});
- --#{$prefix}#{$color}-200: color-mix(in srgb, #fff 60%, #{$hue});
- --#{$prefix}#{$color}-300: color-mix(in srgb, #fff 40%, #{$hue});
- --#{$prefix}#{$color}-400: color-mix(in srgb, #fff 20%, #{$hue});
+ --#{$prefix}#{$color}-025: color-mix(in oklch, #fff 94%, #{$hue});
+ --#{$prefix}#{$color}-050: color-mix(in oklch, #fff 90%, #{$hue});
+ --#{$prefix}#{$color}-100: color-mix(in oklch, #fff 80%, #{$hue});
+ --#{$prefix}#{$color}-200: color-mix(in oklch, #fff 60%, #{$hue});
+ --#{$prefix}#{$color}-300: color-mix(in oklch, #fff 40%, #{$hue});
+ --#{$prefix}#{$color}-400: color-mix(in oklch, #fff 20%, #{$hue});
--#{$prefix}#{$color}-500: #{$hue};
- --#{$prefix}#{$color}-600: color-mix(in srgb, #000 16%, #{$hue});
- --#{$prefix}#{$color}-700: color-mix(in srgb, #000 32%, #{$hue});
- --#{$prefix}#{$color}-800: color-mix(in srgb, #000 48%, #{$hue});
- --#{$prefix}#{$color}-900: color-mix(in srgb, #000 64%, #{$hue});
- --#{$prefix}#{$color}-950: color-mix(in srgb, #000 76%, #{$hue});
- --#{$prefix}#{$color}-975: color-mix(in srgb, #000 88%, #{$hue});
+ --#{$prefix}#{$color}-600: color-mix(in oklch, #000 16%, #{$hue});
+ --#{$prefix}#{$color}-700: color-mix(in oklch, #000 32%, #{$hue});
+ --#{$prefix}#{$color}-800: color-mix(in oklch, #000 48%, #{$hue});
+ --#{$prefix}#{$color}-900: color-mix(in oklch, #000 64%, #{$hue});
+ --#{$prefix}#{$color}-950: color-mix(in oklch, #000 76%, #{$hue});
+ --#{$prefix}#{$color}-975: color-mix(in oklch, #000 88%, #{$hue});
}
}
$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-color: var(--#{$prefix}color-body) !default;
+$dropdown-bg: var(--#{$prefix}bg-body) !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-divider-margin-y: $spacer * .5 !default;
$dropdown-box-shadow: var(--#{$prefix}box-shadow) !default;
-$dropdown-link-color: var(--#{$prefix}body-color) !default;
+$dropdown-link-color: var(--#{$prefix}color-body) !default;
$dropdown-link-hover-color: $dropdown-link-color !default;
$dropdown-link-hover-bg: var(--#{$prefix}tertiary-bg) !default;
@use "layout/breakpoints" as *;
// scss-docs-start list-group-variables
-$list-group-color: var(--#{$prefix}body-color) !default;
-$list-group-bg: var(--#{$prefix}body-bg) !default;
+$list-group-color: var(--#{$prefix}color-body) !default;
+$list-group-bg: var(--#{$prefix}bg-body) !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-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-color: var(--#{$prefix}color-body) !default;
$list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default;
// scss-docs-end list-group-variables
position: relative;
display: block;
padding: var(--#{$prefix}list-group-item-padding-y) var(--#{$prefix}list-group-item-padding-x);
- color: var(--#{$prefix}list-group-color);
+ color: var(--#{$prefix}theme-text, var(--#{$prefix}list-group-color));
text-decoration: if($link-decoration == none, null, none);
- background-color: var(--#{$prefix}list-group-bg);
- border: var(--#{$prefix}list-group-border-width) solid var(--#{$prefix}list-group-border-color);
+ background-color: var(--#{$prefix}theme-bg-subtle, var(--#{$prefix}list-group-bg));
+ border: var(--#{$prefix}list-group-border-width) solid var(--#{$prefix}theme-border, var(--#{$prefix}list-group-border-color));
&:first-child {
@include border-top-radius(inherit);
.list-group-item-action {
width: 100%; // For `<button>`s (anchors become 100% by default though)
- color: var(--#{$prefix}list-group-action-color);
+ color: var(--#{$prefix}theme-text, var(--#{$prefix}list-group-action-color));
text-align: inherit; // For `<button>`s (anchors inherit)
&:not(.active) {
&:hover,
&:focus {
z-index: 1; // Place hover/focus items above their siblings for proper border styling
- color: var(--#{$prefix}list-group-action-hover-color);
+ color: var(--#{$prefix}theme-text-emphasis, var(--#{$prefix}list-group-action-hover-color));
text-decoration: none;
- background-color: var(--#{$prefix}list-group-action-hover-bg);
+ background-color: var(--#{$prefix}theme-bg-muted, var(--#{$prefix}list-group-action-hover-bg));
}
&:active {
- color: var(--#{$prefix}list-group-action-active-color);
- background-color: var(--#{$prefix}list-group-action-active-bg);
+ color: var(--#{$prefix}theme-text-emphasis, var(--#{$prefix}list-group-action-active-color));
+ background-color: var(--#{$prefix}theme-bg-muted, var(--#{$prefix}list-group-action-active-bg));
}
}
}
// Add modifier classes to change text and background color on individual items.
// Organizationally, this must come after the `:hover` states.
- @each $state in map.keys($new-theme-colors) {
- .list-group-item-#{$state} {
- --#{$prefix}list-group-color: var(--#{$prefix}#{$state}-text-emphasis);
- --#{$prefix}list-group-bg: var(--#{$prefix}#{$state}-bg-subtle);
- --#{$prefix}list-group-border-color: var(--#{$prefix}#{$state}-border-subtle);
- --#{$prefix}list-group-action-hover-color: var(--#{$prefix}emphasis-color);
- --#{$prefix}list-group-action-hover-bg: var(--#{$prefix}#{$state}-border-subtle);
- --#{$prefix}list-group-action-active-color: var(--#{$prefix}emphasis-color);
- --#{$prefix}list-group-action-active-bg: var(--#{$prefix}#{$state}-border-subtle);
- --#{$prefix}list-group-active-color: var(--#{$prefix}#{$state}-bg-subtle);
- --#{$prefix}list-group-active-bg: var(--#{$prefix}#{$state}-text-emphasis);
- --#{$prefix}list-group-active-border-color: var(--#{$prefix}#{$state}-text-emphasis);
- }
- }
+ // @each $state in map.keys($new-theme-colors) {
+ // .list-group-item-#{$state} {
+
+ // --#{$prefix}list-group-color: var(--#{$prefix}#{$state}-text-emphasis);
+ // --#{$prefix}list-group-bg: var(--#{$prefix}#{$state}-bg-subtle);
+ // --#{$prefix}list-group-border-color: var(--#{$prefix}#{$state}-border-subtle);
+ // --#{$prefix}list-group-action-hover-color: var(--#{$prefix}emphasis-color);
+ // --#{$prefix}list-group-action-hover-bg: var(--#{$prefix}#{$state}-border-subtle);
+ // --#{$prefix}list-group-action-active-color: var(--#{$prefix}emphasis-color);
+ // --#{$prefix}list-group-action-active-bg: var(--#{$prefix}#{$state}-border-subtle);
+ // --#{$prefix}list-group-active-color: var(--#{$prefix}#{$state}-bg-subtle);
+ // --#{$prefix}list-group-active-bg: var(--#{$prefix}#{$state}-text-emphasis);
+ // --#{$prefix}list-group-active-border-color: var(--#{$prefix}#{$state}-text-emphasis);
+ // }
+ // }
// scss-docs-end list-group-modifiers
}
$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-bg: var(--#{$prefix}bg-body) !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;
$pagination-font-size: $font-size-base !default;
$pagination-color: var(--#{$prefix}link-color) !default;
-$pagination-bg: var(--#{$prefix}body-bg) !default;
+$pagination-bg: var(--#{$prefix}bg-body) !default;
$pagination-border-radius: var(--#{$prefix}border-radius) !default;
$pagination-border-width: var(--#{$prefix}border-width) !default;
$pagination-margin-start: calc(-1 * #{$pagination-border-width}) !default;
// scss-docs-start popover-variables
$popover-font-size: $font-size-sm !default;
-$popover-bg: var(--#{$prefix}body-bg) !default;
+$popover-bg: var(--#{$prefix}bg-body) !default;
$popover-max-width: 276px !default;
$popover-border-width: var(--#{$prefix}border-width) !default;
$popover-border-color: var(--#{$prefix}border-color-translucent) !default;
$popover-header-padding-y: .5rem !default;
$popover-header-padding-x: $spacer !default;
-$popover-body-color: var(--#{$prefix}body-color) !default;
+$popover-body-color: var(--#{$prefix}color-body) !default;
$popover-body-padding-y: $spacer !default;
$popover-body-padding-x: $spacer !default;
}
@each $color, $value in $theme-bgs {
- --#{$prefix}#{$color}: #{$value};
+ --#{$prefix}bg-#{$color}: #{$value};
}
@each $color, $value in $theme-fgs {
- --#{$prefix}#{$color}: #{$value};
+ --#{$prefix}color-#{$color}: #{$value};
}
@each $color, $value in $theme-borders {
- --#{$prefix}#{$color}: #{$value};
+ --#{$prefix}border-#{$color}: #{$value};
}
--#{$prefix}black: #{$black};
:root,
[data-bs-theme="light"] {
+ color-scheme: light;
+
// Note: Custom variable values only support SassScript inside `#{}`.
--#{$prefix}white-rgb: #{to-rgb($white)};
--#{$prefix}border#{$key}: #{$value};
}
- --#{$prefix}body-color: #{$body-color};
+ // --#{$prefix}body-color: #{$body-color};
--#{$prefix}body-color-rgb: #{to-rgb($body-color)};
- --#{$prefix}body-bg: #{$body-bg};
+ // --#{$prefix}body-bg: #{$body-bg};
--#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};
// --#{$prefix}emphasis-color: #{$body-emphasis-color};
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}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}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)};
+ // --#{$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)};
--#{$prefix}heading-color: #{$headings-color-dark};
// --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color-dark)};
// --#{$prefix}code-color: #{$code-color-dark}; // removed in v6
- --#{$prefix}highlight-color: #{$mark-color-dark};
- --#{$prefix}highlight-bg: #{$mark-bg-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};
@return $result;
}
+// Generate theme classes dynamically based on the keys in each theme color map
+@mixin generate-theme-classes() {
+ @each $color-name, $color-map in $new-theme-colors {
+ .theme-#{$color-name} {
+ @each $key, $value in $color-map {
+ --#{$prefix}theme-#{$key}: var(--#{$prefix}#{$color-name}-#{$key});
+ }
+ }
+ }
+}
+
// Recursive mixin to handle nested maps
@mixin create-css-vars($map, $parent-key: "") {
@each $key, $value in $map {
$new-theme-colors: (
"primary": (
"base": var(--#{$prefix}blue-500),
- "text": light-dark(var(--#{$prefix}blue-600), var(--#{$prefix}blue-300)),
+ "text": light-dark(var(--#{$prefix}blue-600), var(--#{$prefix}blue-400)),
+ "text-emphasis": light-dark(var(--#{$prefix}blue-800), var(--#{$prefix}blue-200)),
"bg": light-dark(var(--#{$prefix}blue-500), var(--#{$prefix}blue-500)),
"bg-subtle": light-dark(var(--#{$prefix}blue-100), var(--#{$prefix}blue-900)),
"bg-muted": light-dark(var(--#{$prefix}blue-200), var(--#{$prefix}blue-800)),
"border": light-dark(var(--#{$prefix}blue-300), var(--#{$prefix}blue-600)),
- "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}blue-500), var(--#{$prefix}blue-300)) 50%, var(--#{$prefix}bg)),
+ "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}blue-500), var(--#{$prefix}blue-400)) 50%, var(--#{$prefix}bg-body)),
"contrast": var(--#{$prefix}white)
),
"accent": (
"base": var(--#{$prefix}indigo-500),
- "text": light-dark(var(--#{$prefix}indigo-600), var(--#{$prefix}indigo-300)),
+ "text": light-dark(var(--#{$prefix}indigo-600), color-mix(in oklch, var(--#{$prefix}indigo-400), var(--#{$prefix}indigo-300))),
+ "text-emphasis": light-dark(var(--#{$prefix}indigo-800), var(--#{$prefix}indigo-300)),
"bg": light-dark(var(--#{$prefix}indigo-500), var(--#{$prefix}indigo-500)),
"bg-subtle": light-dark(var(--#{$prefix}indigo-100), var(--#{$prefix}indigo-900)),
"bg-muted": light-dark(var(--#{$prefix}indigo-200), var(--#{$prefix}indigo-800)),
"border": light-dark(var(--#{$prefix}indigo-300), var(--#{$prefix}indigo-600)),
- "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}indigo-500), var(--#{$prefix}indigo-300)) 50%, var(--#{$prefix}bg)),
+ "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}indigo-500), var(--#{$prefix}indigo-400)) 50%, var(--#{$prefix}bg-body)),
+ "contrast": var(--#{$prefix}white)
+ ),
+ "success": (
+ "base": var(--#{$prefix}green-500),
+ "text": light-dark(var(--#{$prefix}green-600), var(--#{$prefix}green-400)),
+ "text-emphasis": light-dark(var(--#{$prefix}green-800), var(--#{$prefix}green-300)),
+ "bg": light-dark(var(--#{$prefix}green-500), var(--#{$prefix}green-500)),
+ "bg-subtle": light-dark(var(--#{$prefix}green-100), var(--#{$prefix}green-900)),
+ "bg-muted": light-dark(var(--#{$prefix}green-200), var(--#{$prefix}green-800)),
+ "border": light-dark(var(--#{$prefix}green-300), var(--#{$prefix}green-600)),
+ "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}green-500), var(--#{$prefix}green-400)) 50%, var(--#{$prefix}bg-body)),
"contrast": var(--#{$prefix}white)
),
"danger": (
"base": var(--#{$prefix}red-500),
- "text": light-dark(var(--#{$prefix}red-600), var(--#{$prefix}red-300)),
+ "text": light-dark(var(--#{$prefix}red-600), var(--#{$prefix}red-400)),
+ "text-emphasis": light-dark(var(--#{$prefix}red-800), var(--#{$prefix}red-300)),
"bg": light-dark(var(--#{$prefix}red-500), var(--#{$prefix}red-500)),
"bg-subtle": light-dark(var(--#{$prefix}red-100), var(--#{$prefix}red-900)),
"bg-muted": light-dark(var(--#{$prefix}red-200), var(--#{$prefix}red-800)),
"border": light-dark(var(--#{$prefix}red-300), var(--#{$prefix}red-600)),
- "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}red-500), var(--#{$prefix}red-300)) 50%, var(--#{$prefix}bg)),
+ "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}red-500), var(--#{$prefix}red-400)) 50%, var(--#{$prefix}bg-body)),
"contrast": var(--#{$prefix}white)
),
"warning": (
"base": var(--#{$prefix}yellow-500),
- "text": light-dark(var(--#{$prefix}yellow-700), var(--#{$prefix}yellow-300)),
+ "text": light-dark(var(--#{$prefix}yellow-700), var(--#{$prefix}yellow-400)),
+ "text-emphasis": light-dark(var(--#{$prefix}yellow-800), var(--#{$prefix}yellow-300)),
"bg": light-dark(var(--#{$prefix}yellow-500), var(--#{$prefix}yellow-500)),
"bg-subtle": light-dark(var(--#{$prefix}yellow-100), var(--#{$prefix}yellow-900)),
"bg-muted": light-dark(var(--#{$prefix}yellow-200), var(--#{$prefix}yellow-800)),
"border": light-dark(var(--#{$prefix}yellow-300), var(--#{$prefix}yellow-600)),
- "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}yellow-500), var(--#{$prefix}yellow-300)) 50%, var(--#{$prefix}bg)),
+ "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}yellow-500), var(--#{$prefix}yellow-400)) 50%, var(--#{$prefix}bg-body)),
"contrast": var(--#{$prefix}gray-900)
),
- "success": (
- "base": var(--#{$prefix}green-500),
- "text": light-dark(var(--#{$prefix}green-600), var(--#{$prefix}green-300)),
- "bg": light-dark(var(--#{$prefix}green-500), var(--#{$prefix}green-500)),
- "bg-subtle": light-dark(var(--#{$prefix}green-100), var(--#{$prefix}green-900)),
- "bg-muted": light-dark(var(--#{$prefix}green-200), var(--#{$prefix}green-800)),
- "border": light-dark(var(--#{$prefix}green-300), var(--#{$prefix}green-600)),
- "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}green-500), var(--#{$prefix}green-300)) 50%, var(--#{$prefix}bg)),
- "contrast": var(--#{$prefix}white)
- ),
"info": (
"base": var(--#{$prefix}cyan-500),
- "text": light-dark(var(--#{$prefix}cyan-600), var(--#{$prefix}cyan-300)),
+ "text": light-dark(var(--#{$prefix}cyan-600), var(--#{$prefix}cyan-400)),
+ "text-emphasis": light-dark(var(--#{$prefix}cyan-800), var(--#{$prefix}cyan-300)),
"bg": light-dark(var(--#{$prefix}cyan-500), var(--#{$prefix}cyan-500)),
"bg-subtle": light-dark(var(--#{$prefix}cyan-100), var(--#{$prefix}cyan-900)),
"bg-muted": light-dark(var(--#{$prefix}cyan-200), var(--#{$prefix}cyan-800)),
"border": light-dark(var(--#{$prefix}cyan-300), var(--#{$prefix}cyan-600)),
- "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}cyan-500), var(--#{$prefix}cyan-300)) 50%, var(--#{$prefix}bg)),
+ "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}cyan-500), var(--#{$prefix}cyan-400)) 50%, var(--#{$prefix}bg-body)),
"contrast": var(--#{$prefix}gray-900)
),
+ "inverse": (
+ "base": var(--#{$prefix}gray-900),
+ "text": light-dark(var(--#{$prefix}gray-900), var(--#{$prefix}gray-200)),
+ "text-emphasis": light-dark(var(--#{$prefix}gray-975), var(--#{$prefix}white)),
+ "bg": light-dark(var(--#{$prefix}gray-900), var(--#{$prefix}gray-025)),
+ "bg-subtle": light-dark(var(--#{$prefix}gray-100), var(--#{$prefix}gray-900)),
+ "bg-muted": light-dark(var(--#{$prefix}gray-200), var(--#{$prefix}gray-300)),
+ "border": light-dark(var(--#{$prefix}gray-400), var(--#{$prefix}gray-100)),
+ "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}gray-900), var(--#{$prefix}gray-100)) 50%, var(--#{$prefix}bg-body)),
+ "contrast": light-dark(var(--#{$prefix}white), var(--#{$prefix}gray-900))
+ ),
"secondary": (
- "base": var(--#{$prefix}gray-300),
+ "base": var(--#{$prefix}gray-200),
"text": light-dark(var(--#{$prefix}gray-600), var(--#{$prefix}gray-400)),
- "bg": light-dark(var(--#{$prefix}gray-300), var(--#{$prefix}gray-600)),
- "bg-subtle": light-dark(var(--#{$prefix}gray-100), var(--#{$prefix}gray-800)),
- "bg-muted": light-dark(var(--#{$prefix}gray-200), var(--#{$prefix}gray-700)),
+ "text-emphasis": light-dark(var(--#{$prefix}gray-800), var(--#{$prefix}gray-200)),
+ "bg": light-dark(var(--#{$prefix}gray-100), var(--#{$prefix}gray-600)),
+ "bg-subtle": light-dark(var(--#{$prefix}gray-050), var(--#{$prefix}gray-800)),
+ "bg-muted": light-dark(var(--#{$prefix}gray-100), var(--#{$prefix}gray-700)),
"border": light-dark(var(--#{$prefix}gray-300), var(--#{$prefix}gray-600)),
- "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}gray-500), var(--#{$prefix}gray-300)) 50%, var(--#{$prefix}bg)),
+ "focus-ring": color-mix(in oklch, light-dark(var(--#{$prefix}gray-500), var(--#{$prefix}gray-300)) 50%, var(--#{$prefix}bg-body)),
"contrast": light-dark(var(--#{$prefix}gray-900), var(--#{$prefix}white))
)
) !default;
// scss-docs-end theme-colors
+// Generate theme modifier classes (e.g., .theme-primary, .theme-accent, etc.)
+@include generate-theme-classes();
+
// mdo-do: consider using muted, subtle, ghost or something instead of linear scale?
$theme-bgs: (
- null: light-dark(var(--#{$prefix}white), var(--#{$prefix}gray-975)),
+ "body": light-dark(var(--#{$prefix}white), var(--#{$prefix}gray-975)),
"1": light-dark(var(--#{$prefix}gray-025), var(--#{$prefix}gray-950)),
"2": light-dark(var(--#{$prefix}gray-050), var(--#{$prefix}gray-900)),
"3": light-dark(var(--#{$prefix}gray-100), var(--#{$prefix}gray-800)),
) !default;
$theme-fgs: (
- null: light-dark(var(--#{$prefix}gray-900), var(--#{$prefix}gray-050)),
- "1": light-dark(var(--#{$prefix}gray-800), var(--#{$prefix}gray-100)),
- "2": light-dark(var(--#{$prefix}gray-700), var(--#{$prefix}gray-200)),
- "3": light-dark(var(--#{$prefix}gray-600), var(--#{$prefix}gray-300)),
+ "body": light-dark(var(--#{$prefix}gray-900), var(--#{$prefix}gray-050)),
+ "1": light-dark(var(--#{$prefix}gray-800), var(--#{$prefix}gray-200)),
+ "2": light-dark(var(--#{$prefix}gray-700), var(--#{$prefix}gray-300)),
+ "3": light-dark(var(--#{$prefix}gray-600), var(--#{$prefix}gray-500)),
"white": var(--#{$prefix}white),
"black": var(--#{$prefix}black),
"inherit": inherit,
) !default;
$theme-borders: (
- null: light-dark(var(--#{$prefix}gray-300), var(--#{$prefix}gray-700)),
+ null: light-dark(var(--#{$prefix}gray-300), var(--#{$prefix}gray-800)),
"muted": light-dark(var(--#{$prefix}gray-200), var(--#{$prefix}gray-800)),
- "subtle": light-dark(var(--#{$prefix}gray-100), color-mix(in srgb, var(--#{$prefix}gray-800), var(--#{$prefix}gray-900))),
+ "subtle": light-dark(var(--#{$prefix}gray-100), var(--#{$prefix}gray-900)),
"emphasized": light-dark(var(--#{$prefix}gray-400), var(--#{$prefix}gray-600)),
) !default;
// 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}body-color) !default;
+$tooltip-color: var(--#{$prefix}bg-body) !default;
+$tooltip-bg: var(--#{$prefix}color-body) !default;
$tooltip-border-radius: var(--#{$prefix}border-radius) !default;
$tooltip-opacity: .9 !default;
$tooltip-padding-y: $spacer * .25 !default;
// Settings for the `<body>` element.
$body-text-align: null !default;
-$body-color: var(--#{$prefix}gray-900) !default;
-$body-bg: $white !default;
+$body-color: var(--#{$prefix}color-body) !default;
+$body-bg: var(--#{$prefix}bg-body) !default;
-$body-secondary-color: rgba($body-color, .75) !default;
-$body-secondary-bg: var(--#{$prefix}gray-200) !default;
+$body-secondary-color: var(--#{$prefix}color-secondary) !default;
+$body-secondary-bg: var(--#{$prefix}bg-secondary) !default;
-$body-tertiary-color: rgba($body-color, .5) !default;
-$body-tertiary-bg: var(--#{$prefix}gray-100) !default;
+$body-tertiary-color: var(--#{$prefix}color-muted) !default;
+$body-tertiary-bg: var(--#{$prefix}bg-muted) !default;
$body-emphasis-color: $black !default;
// 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-color: var(--#{$prefix}color-body) !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;
$modal-title-line-height: $line-height-base !default;
-$modal-content-color: var(--#{$prefix}body-color) !default;
-$modal-content-bg: var(--#{$prefix}body-bg) !default;
+$modal-content-color: var(--#{$prefix}color-body) !default;
+$modal-content-bg: var(--#{$prefix}bg-body) !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;
$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-bg-color: var(--#{$prefix}bg-body) !default;
+$offcanvas-color: var(--#{$prefix}color-body) !default;
$offcanvas-box-shadow: $modal-content-box-shadow-xs !default;
$offcanvas-backdrop-bg: $modal-backdrop-bg !default;
$offcanvas-backdrop-opacity: $modal-backdrop-opacity !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;
+$kbd-color: var(--#{$prefix}bg-body) !default;
+$kbd-bg: var(--#{$prefix}color-body) !default;
$pre-color: null !default;
//
// scss-docs-start sass-dark-mode-vars
-$body-color-dark: var(--#{$prefix}gray-200) !default;
-$body-bg-dark: var(--#{$prefix}gray-975) !default;
-$body-secondary-color-dark: rgba($body-color-dark, .75) !default;
-$body-secondary-bg-dark: var(--#{$prefix}gray-800) !default;
-$body-tertiary-color-dark: rgba($body-color-dark, .5) !default;
+// $body-color-dark: var(--#{$prefix}gray-200) !default;
+// $body-bg-dark: var(--#{$prefix}gray-975) !default;
+// $body-secondary-color-dark: rgba($body-color-dark, .75) !default;
+// $body-secondary-bg-dark: var(--#{$prefix}gray-800) !default;
+// $body-tertiary-color-dark: rgba($body-color-dark, .5) !default;
$body-tertiary-bg-dark: color-mix(in srgb, var(--#{$prefix}gray-800), var(--#{$prefix}gray-900)) !default;
$body-emphasis-color-dark: $white !default;
$border-color-dark: var(--#{$prefix}gray-700) !default;
$border-color-translucent-dark: rgba($white, .15) !default;
$headings-color-dark: inherit !default;
-$mark-color-dark: $body-color-dark !default;
+// $mark-color-dark: $body-color-dark !default;
$mark-bg-dark: var(--#{$prefix}yellow-800) !default;
@use "../forms/form-variables" as *;
// scss-docs-start btn-variables
-$btn-color: var(--#{$prefix}body-color) !default;
+$btn-color: var(--#{$prefix}color-body) !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;
@use "sass:color";
+@use "sass:list";
+@use "sass:map";
+@use "sass:meta";
@use "../colors" as *;
@use "../config" as *;
-@use "../variables" as *;
@use "../theme" as *;
+@use "../variables" as *;
@use "../functions" as *;
@use "../vendor/rfs" as *;
@use "../mixins/border-radius" as *;
@use "../mixins/transition" as *;
@use "button-variables" as *;
-// 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(color.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-start btn-variants
+$button-variants: (
+ "solid": (
+ "base": (
+ "bg": "bg",
+ "color": "contrast",
+ "border-color": "bg"
+ ),
+ "hover": (
+ "bg": "bg",
+ "border-color": "bg",
+ "color": "contrast"
+ ),
+ "active": (
+ "bg": "bg",
+ "border-color": "bg",
+ "color": "contrast"
+ )
+ ),
+ "outline": (
+ "base": (
+ "bg": "transparent",
+ "color": "text",
+ "border-color": "border"
+ ),
+ "hover": (
+ "bg": "bg",
+ "color": "contrast",
+ "border-color": "bg"
+ ),
+ "active": (
+ "bg": "bg",
+ "color": "contrast",
+ "border-color": "bg"
+ )
+ ),
+ "subtle": (
+ "base": (
+ "bg": "bg-subtle",
+ "color": "text",
+ "border-color": "transparent"
+ ),
+ "hover": (
+ "bg": ("bg-muted", "bg-subtle"),
+ "color": "text-emphasis"
+ ),
+ "active": (
+ "bg": "bg-subtle",
+ "color": "text-emphasis"
+ )
+ ),
+ "text": (
+ "base": (
+ "color": "text",
+ "bg": "transparent",
+ "border-color": "transparent"
+ ),
+ "hover": (
+ "color": "text",
+ "bg": "bg-subtle"
+ ),
+ "active": (
+ "color": "text",
+ "bg": "bg-subtle"
+ )
+ )
+) !default;
+// scss-docs-end btn-variants
+
+
+// // Helper function to get nested map values using dot notation
+// @function get-nested-value($map, $keys) {
+// $value: $map;
+// @each $key in $keys {
+// @if type-of($value) == "map" {
+// $value: map-get($value, $key);
+// } @else {
+// @return null;
+// }
+// }
+// @return $value;
+// }
+
+// // Helper function to split dot notation string into list
+// @function split-keys($key) {
+// $keys: ();
+// $parts: str-slice($key, 1);
+// @each $part in $parts {
+// $keys: append($keys, $part);
+// }
+// @return $keys;
// }
-// 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;
+
+// // Main button style generator mixin
+// // scss-docs-start btn-variant-mixin
+// @mixin button-variant($color, $variant) {
+// $variant-styles: map.get($button-variants, $variant);
+
+// @if $variant-styles {
+// // Base properties
+// @each $property, $value in map.get($variant-styles, "base") {
+// @if $value == "transparent" {
+// --#{$prefix}btn-#{$property}: transparent;
+// } @else {
+// --#{$prefix}btn-#{$property}: var(--#{$prefix}#{$color}-#{$value});
+// }
+// }
+
+// // Hover state
+// &:hover {
+// @each $property, $value in map.get($variant-styles, "hover") {
+// @if $value == "transparent" {
+// --#{$prefix}btn-hover-#{$property}: transparent;
+// } @else if meta.type-of($value) == "list" {
+// $first-value: list.nth($value, 1);
+// $second-value: list.nth($value, 2);
+// --#{$prefix}btn-hover-#{$property}: color-mix(in oklch, var(--#{$prefix}#{$color}-#{$first-value}) 50%, var(--#{$prefix}#{$color}-#{$second-value}));
+// } @else if $value == "bg-subtle" {
+// --#{$prefix}btn-hover-#{$property}: var(--#{$prefix}#{$color}-#{$value});
+// } @else {
+// --#{$prefix}btn-hover-#{$property}: oklch(from var(--#{$prefix}#{$color}-#{$value}) calc(l * .95) calc(c * 1.1) h);
+// }
+// }
+// }
+
+// &:focus-visible {
+// outline-color: var(--#{$prefix}#{$color}-focus-ring);
+// }
+
+// // Active state
+// &:active,
+// &.active {
+// @each $property, $value in map.get($variant-styles, "active") {
+// @if $value == "transparent" {
+// --#{$prefix}btn-active-#{$property}: transparent;
+// } @else if $value == "bg-subtle" {
+// --#{$prefix}btn-active-#{$property}: var(--#{$prefix}#{$color}-#{$value});
+// } @else {
+// --#{$prefix}btn-active-#{$property}: oklch(from var(--#{$prefix}#{$color}-#{$value}) calc(l * .9) calc(c * 1.15) h);
+// }
+// }
+// }
+// }
// }
-// scss-docs-end btn-outline-variant-mixin
+// // scss-docs-end btn-variant-mixin
+
+// Generate button variant classes (e.g., .btn-solid, .btn-outline, etc.)
+@each $variant, $_ in $button-variants {
+ .btn-#{$variant} {
+ // Base properties
+ @each $property, $value in map.get($button-variants, $variant, "base") {
+ @if $value == "transparent" {
+ --#{$prefix}btn-#{$property}: transparent;
+ } @else {
+ --#{$prefix}btn-#{$property}: var(--#{$prefix}theme-#{$value});
+ }
+ }
+
+ // Hover state
+ &:hover {
+ @each $property, $value in map.get($button-variants, $variant, "hover") {
+ @if $value == "transparent" {
+ --#{$prefix}btn-hover-#{$property}: transparent;
+ } @else if meta.type-of($value) == "list" {
+ $first-value: list.nth($value, 1);
+ $second-value: list.nth($value, 2);
+ --#{$prefix}btn-hover-#{$property}: color-mix(in oklch, var(--#{$prefix}theme-#{$first-value}) 50%, var(--#{$prefix}theme-#{$second-value}));
+ } @else if $value == "bg-subtle" {
+ --#{$prefix}btn-hover-#{$property}: var(--#{$prefix}theme-#{$value});
+ } @else {
+ --#{$prefix}btn-hover-#{$property}: oklch(from var(--#{$prefix}theme-#{$value}) calc(l * .95) calc(c * 1.1) h);
+ }
+ }
+ }
+
+ &:focus-visible {
+ outline-color: var(--#{$prefix}theme-focus-ring);
+ }
+
+ // Active state
+ &:active,
+ &.active {
+ @each $property, $value in map.get($button-variants, $variant, "active") {
+ @if $value == "transparent" {
+ --#{$prefix}btn-active-#{$property}: transparent;
+ } @else if $value == "bg-subtle" {
+ --#{$prefix}btn-active-#{$property}: var(--#{$prefix}theme-#{$value});
+ } @else {
+ --#{$prefix}btn-active-#{$property}: oklch(from var(--#{$prefix}theme-#{$value}) calc(l * .9) calc(c * 1.15) h);
+ }
+ }
+ }
+ }
+}
// scss-docs-start btn-size-mixin
@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {
}
// scss-docs-end btn-size-mixin
-
//
// Base styles
//
@layer components {
- .btn {
+ .btn,
+ [class*="btn-"] {
// scss-docs-start btn-css-vars
--#{$prefix}btn-padding-x: #{$btn-padding-x};
--#{$prefix}btn-padding-y: #{$btn-padding-y};
}
&:focus-visible {
- color: var(--#{$prefix}btn-hover-color);
- @include gradient-bg(var(--#{$prefix}btn-hover-bg));
- border-color: var(--#{$prefix}btn-hover-border-color);
@include focus-ring(true);
--#{$prefix}focus-ring-offset: 1px;
}
.btn-check:focus-visible + & {
- border-color: var(--#{$prefix}btn-hover-border-color);
@include focus-ring(true);
}
}
}
-
- //
- // Alternate buttons
- //
-
- // scss-docs-start btn-variant-loops
- // @each $color, $value in $new-theme-colors {
- // .btn-#{$color} {
- // @if $color == "light" {
- // @include button-variant(
- // $value,
- // $value,
- // $hover-background: shade-color($value, $btn-hover-bg-shade-amount),
- // $hover-border: shade-color($value, $btn-hover-border-shade-amount),
- // $active-background: shade-color($value, $btn-active-bg-shade-amount),
- // $active-border: shade-color($value, $btn-active-border-shade-amount)
- // );
- // } @else if $color == "dark" {
- // @include button-variant(
- // $value,
- // $value,
- // $hover-background: tint-color($value, $btn-hover-bg-tint-amount),
- // $hover-border: tint-color($value, $btn-hover-border-tint-amount),
- // $active-background: tint-color($value, $btn-active-bg-tint-amount),
- // $active-border: tint-color($value, $btn-active-border-tint-amount)
- // );
- // } @else {
- // @include button-variant($value, $value);
- // }
- // }
- // }
-
- // @each $color, $value in $new-theme-colors {
- // .btn-outline-#{$color} {
- // @include button-outline-variant($value);
- // }
- // }
- // scss-docs-end btn-variant-loops
-
-
//
// Link buttons
//
// scss-docs-start thumbnail-variables
$thumbnail-padding: .25rem !default;
-$thumbnail-bg: var(--#{$prefix}body-bg) !default;
+$thumbnail-bg: var(--#{$prefix}bg-body) !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;
@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);
+ color: var(--#{$prefix}color-body);
text-align: var(--#{$prefix}body-text-align);
- background-color: var(--#{$prefix}body-bg); // 2
+ background-color: var(--#{$prefix}bg-body); // 2
-webkit-text-size-adjust: 100%; // 3
-webkit-tap-highlight-color: rgba($black, 0); // 4
}
$table-cell-vertical-align: top !default;
-$table-color: var(--#{$prefix}body-color) !default;
-$table-bg: var(--#{$prefix}body-bg) !default;
+$table-color: var(--#{$prefix}color-body) !default;
+$table-bg: var(--#{$prefix}bg-body) !default;
$table-accent-bg: transparent !default;
// $table-th-font-weight: null !default;
$control-padding-x: .75rem !default;
$control-font-size: $font-size-base !default;
$control-line-height: $line-height-base !default;
-$control-color: var(--#{$prefix}body-color) !default;
-$control-bg: var(--#{$prefix}body-bg) !default;
+$control-color: var(--#{$prefix}color-body) !default;
+$control-bg: var(--#{$prefix}bg-body) !default;
$control-border-width: var(--#{$prefix}border-width) !default;
$control-border-color: var(--#{$prefix}border-color) !default;
$control-border-radius: var(--#{$prefix}border-radius) !default;
$control-select-bg-position: right $control-padding-x center !default;
$control-select-bg-size: 16px 12px !default;
-$control-select-indicator-color-dark: $body-color-dark !default;
+$control-select-indicator-color-dark: #fff !default;
$control-select-indicator-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$control-select-indicator-color-dark}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/></svg>") !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-bg: var(--#{$prefix}bg-body) !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-color: var(--#{$prefix}color-body) !default;
$input-border-color: var(--#{$prefix}border-color) !default;
$input-border-width: var(--#{$prefix}border-width) !default;
$input-box-shadow: var(--#{$prefix}box-shadow-inset) !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-plaintext-color: var(--#{$prefix}color-body) !default;
$input-height-border: calc(#{$input-border-width} * 2) !default;
- name: danger
- name: warning
- name: info
+- name: inverse
- name: secondary
size?: 'inline' | 'medium' | 'large'
contrast?: string
contrastDark?: string
+ showVar?: boolean
}
-const { bg, fg, size = 'inline', contrast, contrastDark } = Astro.props
+const { bg, fg, size = 'inline', contrast, contrastDark, showVar = true } = Astro.props
// Styles for different sizes
const baseStyles = {
}
const combinedStyles = { ...baseStyles, ...sizeStyles[size] }
+
+// Use bg prop as the CSS variable name
+const displayCssVar = bg
---
<style>
:global([data-bs-theme="dark"]) .contrast-dark {
display: inline;
}
+
+ /* CSS variable display styles */
+ .css-var {
+ margin-left: 0.25rem;
+ color: var(--bs-color-3);
+ }
+
+ .css-var-light {
+ display: inline;
+ }
+
+ .css-var-dark {
+ display: none;
+ }
+
+ /* Show dark value in dark mode */
+ :global([data-bs-theme="dark"]) .css-var-light {
+ display: none;
+ }
+
+ :global([data-bs-theme="dark"]) .css-var-dark {
+ display: inline;
+ }
</style>
{size === 'inline' ? (
- <span style={combinedStyles}>
- <slot />
- {contrast && <span style={contrastStyles} class="contrast-light">{contrast}</span>}
- {contrastDark && <span style={{...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit'}} class="contrast-dark">{contrastDark}</span>}
- </span>
+ <>
+ <span style={combinedStyles}>
+ <slot />
+ {contrast && <span style={contrastStyles} class="contrast-light">{contrast}</span>}
+ {contrastDark && <span style={{...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit'}} class="contrast-dark">{contrastDark}</span>}
+ </span>
+ {showVar && displayCssVar && (
+ <code class="css-var" data-css-var={`--bs-${displayCssVar}`}>
+ <span class="css-var-light">Loading...</span>
+ <span class="css-var-dark">Loading...</span>
+ </code>
+ )}
+ </>
) : size === 'large' ? (
<span style={combinedStyles}>
<slot />
{contrastDark && <span style={{...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit'}} class="contrast-dark">{contrastDark}</span>}
</div>
)}
+
+<script>
+ // Handle dynamic CSS variable display with light-dark() function support
+ document.addEventListener('DOMContentLoaded', () => {
+ const cssVarElements = document.querySelectorAll('.css-var[data-css-var]')
+
+ cssVarElements.forEach(element => {
+ const cssVarName = element.getAttribute('data-css-var')
+
+ if (cssVarName) {
+ // Try to get the raw CSS variable definition from stylesheets
+ let rawValue = null
+ for (const stylesheet of document.styleSheets) {
+ try {
+ for (const rule of stylesheet.cssRules) {
+ if (rule.type === CSSRule.STYLE_RULE) {
+ const styleRule = rule as CSSStyleRule
+ for (const prop of styleRule.style) {
+ if (prop === cssVarName) {
+ rawValue = styleRule.style.getPropertyValue(cssVarName)
+ break
+ }
+ }
+ }
+ }
+ } catch (e) {
+ // Skip stylesheets we can't access (CORS)
+ continue
+ }
+ }
+
+ // If we couldn't get the raw value, fall back to computed value
+ if (!rawValue) {
+ rawValue = getComputedStyle(document.documentElement).getPropertyValue(cssVarName)
+ }
+
+ if (rawValue) {
+ // Check if the value contains light-dark function
+ if (rawValue.includes('light-dark(')) {
+ // Parse the light-dark function to extract light and dark values
+ const lightDarkMatch = rawValue.match(/light-dark\(([^,]+),\s*(.+)\)$/)
+ if (lightDarkMatch) {
+ const lightValue = lightDarkMatch[1].trim()
+ const darkValue = lightDarkMatch[2].trim()
+
+ // Update the spans with the parsed values
+ const lightSpan = element.querySelector('.css-var-light')
+ const darkSpan = element.querySelector('.css-var-dark')
+
+ if (lightSpan) lightSpan.textContent = lightValue
+ if (darkSpan) darkSpan.textContent = darkValue
+ } else {
+ // Fallback: show the full value
+ element.innerHTML = `<span class="css-var-light">${rawValue}</span>`
+ }
+ } else if (rawValue.includes('color-mix(')) {
+ // Handle color-mix functions - show the full function
+ element.innerHTML = `<span class="css-var-light">${rawValue}</span>`
+ } else {
+ // Single value - show it in both light and dark spans
+ element.innerHTML = `<span class="css-var-light">${rawValue}</span>`
+ }
+ } else {
+ // Fallback: show the variable name
+ element.innerHTML = `<span class="css-var-light">${cssVarName}</span>`
+ }
+ }
+ })
+ })
+</script>
Alerts are available for any length of text, as well as an optional close button. For proper styling, use one of the eight **required** contextual classes (e.g., `.alert-success`). For inline dismissal, use the [alerts JavaScript plugin](#dismissing).
-<Example code={getData('theme-colors').map((themeColor) => `<div class="alert alert-${themeColor.name}" role="alert">
+<Example code={getData('theme-colors').map((themeColor) => `<div class="alert theme-${themeColor.name}" role="alert">
A simple ${themeColor.name} alert—check it out!
</div>`)} />
### Headings
-<Example code={`<h1>Example heading <span class="badge text-bg-secondary">New</span></h1>
-<h2>Example heading <span class="badge text-bg-secondary">New</span></h2>
-<h3>Example heading <span class="badge text-bg-secondary">New</span></h3>
-<h4>Example heading <span class="badge text-bg-secondary">New</span></h4>
-<h5>Example heading <span class="badge text-bg-secondary">New</span></h5>
-<h6>Example heading <span class="badge text-bg-secondary">New</span></h6>`} />
+<Example code={`<h1>Example heading <span class="badge">New</span></h1>
+<h2>Example heading <span class="badge">New</span></h2>
+<h3>Example heading <span class="badge">New</span></h3>
+<h4>Example heading <span class="badge">New</span></h4>
+<h5>Example heading <span class="badge">New</span></h5>
+<h6>Example heading <span class="badge">New</span></h6>`} />
### Buttons
Badges can be used as part of links or buttons to provide a counter.
<Example code={`<button type="button" class="btn btn-primary">
- Notifications <span class="badge text-bg-secondary">4</span>
+ Notifications <span class="badge theme-danger">4</span>
</button>`} />
Note that depending on how they are used, badges may be confusing for users of screen readers and similar assistive technologies. While the styling of badges provides a visual cue as to their purpose, these users will simply be presented with the content of the badge. Depending on the specific situation, these badges may seem like random additional words or numbers at the end of a sentence, link, or button.
<Example code={`<button type="button" class="btn btn-primary position-relative">
Inbox
- <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
+ <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill theme-danger">
99+
<span class="visually-hidden">unread messages</span>
</span>
Set a `background-color` with contrasting foreground `color` with [our `.text-bg-{color}` helpers]([[docsref:helpers/color-background]]). Previously it was required to manually pair your choice of [`.text-{color}`]([[docsref:/utilities/colors]]) and [`.bg-{color}`]([[docsref:/utilities/background]]) utilities for styling, which you still may use if you prefer.
-<Example code={getData('theme-colors').map((themeColor) => `<span class="badge text-bg-${themeColor.name}">${themeColor.title}</span>`)} />
+<Example code={getData('theme-colors').map((themeColor) => `<span class="badge theme-${themeColor.name}">${themeColor.title}</span>`)} />
+<Example code={getData('theme-colors').map((themeColor) => `<span class="badge badge-subtle theme-${themeColor.name}">${themeColor.title}</span>`)} />
<Callout name="warning-color-assistive-technologies" />
Use the `.rounded-pill` utility class to make badges more rounded with a larger `border-radius`.
-<Example code={getData('theme-colors').map((themeColor) => `<span class="badge rounded-pill text-bg-${themeColor.name}">${themeColor.title}</span>`)} />
+<Example code={getData('theme-colors').map((themeColor) => `<span class="badge rounded-pill theme-${themeColor.name}">${themeColor.title}</span>`)} />
## CSS
Bootstrap includes several button variants, each serving its own semantic purpose, with a few extras thrown in for more control.
-<Example code={[...getData('theme-colors').map((themeColor) => `<button type="button" class="btn btn-${themeColor.name}">${themeColor.title}</button>`), `
+<Example class="bd-example-buttons" code={[...getData('theme-colors').map((themeColor) => `<button type="button" class="btn-solid theme-${themeColor.name} justify-self-start">${themeColor.title}</button>
+<button type="button" class="btn-outline theme-${themeColor.name} justify-self-start">${themeColor.title}</button>
+<button type="button" class="btn-subtle theme-${themeColor.name} justify-self-start">${themeColor.title}</button>
+<button type="button" class="btn-text theme-${themeColor.name} justify-self-start">${themeColor.title}</button>
+`), `
<button type="button" class="btn btn-link">Link</button>`]} />
<Callout name="warning-color-assistive-technologies" />
### Sass variables
-<ScssDocs name="btn-variables" file="scss/_variables.scss" />
+<ScssDocs name="btn-variables" file="scss/buttons/_button-variables.scss" />
+
+### Sass map
+
+Button variants—including all their states—are defined in the `$button-variants` Sass map. This map identifies which theme color tokens to use for each variant's state.
+
+For example, a solid button uses the same `bg` token for its background and border colors because we want it to have a seamless look.
+
+<ScssDocs name="btn-variants" file="scss/buttons/_button.scss" />
### Sass mixins
There are three mixins for buttons: button and button outline variant mixins (both based on `$theme-colors`), plus a button size mixin.
-{/*<ScssDocs name="btn-variant-mixin" file="scss/mixins/_buttons.scss" />
+<ScssDocs name="btn-variant-mixin" file="scss/buttons/_button.scss" />
-<ScssDocs name="btn-outline-variant-mixin" file="scss/mixins/_buttons.scss" />
+{/*<ScssDocs name="btn-outline-variant-mixin" file="scss/mixins/_buttons.scss" />
<ScssDocs name="btn-size-mixin" file="scss/mixins/_buttons.scss" />*/}
Button variants (for regular and outline buttons) use their respective mixins with our `$theme-colors` map to generate the modifier classes in `scss/_buttons.scss`.
-<ScssDocs name="btn-variant-loops" file="scss/buttons/_button.scss" />
+{/* <ScssDocs name="btn-variant-loops" file="scss/buttons/_button.scss" /> */}
`<ul class="list-group">
<li class="list-group-item">A simple default list group item</li>
`,
- ...getData('theme-colors').map((themeColor) => ` <li class="list-group-item list-group-item-${themeColor.name}">A simple ${themeColor.name} list group item</li>`),
+ ...getData('theme-colors').map((themeColor) => ` <li class="list-group-item theme-${themeColor.name}">A simple ${themeColor.name} list group item</li>`),
`</ul>`
]} />
`<div class="list-group">
<a href="#" class="list-group-item list-group-item-action">A simple default list group item</a>
`,
- ...getData('theme-colors').map((themeColor) => ` <a href="#" class="list-group-item list-group-item-action list-group-item-${themeColor.name}">A simple ${themeColor.name} list group item</a>`),
+ ...getData('theme-colors').map((themeColor) => ` <a href="#" class="list-group-item list-group-item-action theme-${themeColor.name}">A simple ${themeColor.name} list group item</a>`),
`</div>`
]} />
export const themeTokens = [
'base',
'text',
+ 'text-emphasis',
'bg',
'bg-subtle',
'bg-muted',
]
export const themeBgs = [
- 'null',
- '1',
- '2',
- '3',
+ 'body',
+ 'secondary',
+ 'subtle',
+ 'muted',
'white',
'black',
'transparent',
]
export const themeFgs = [
- 'null',
- '1',
- '2',
- '3',
+ 'body',
+ 'secondary',
+ 'subtle',
+ 'muted',
'white',
'black',
'transparent',
| Theme color | Default value | Description |
| --- | --- | --- |
| `primary` | <Swatch size="inline" bg="blue-500" /> `var(--bs-blue-500)`| Main brand color for primary actions |
-| `accent` | <Swatch size="inline" bg="indigo-500" /> `var(--bs-indigo-500)` | Secondary brand color (new in v6) |
+| `accent` | <Swatch size="inline" bg="indigo-500" /> `var(--bs-indigo-500)` | Complementary brand color option |
| `success` | <Swatch size="inline" bg="green-500" /> `var(--bs-green-500)` | Positive actions and successful states |
| `danger` | <Swatch size="inline" bg="red-500" /> `var(--bs-red-500)` | Destructive actions and error states |
-| `warning` | <Swatch size="inline" bg="yellow-500" /> `var(--bs-yellow-500)` | Cautionary messages and warning states |
+| `warning` | <Swatch size="inline" bg="yellow-500" /> `var(--bs-yellow-500)` | Cautionary messages and states |
| `info` | <Swatch size="inline" bg="cyan-500" /> `var(--bs-cyan-500)` | Informational messages and neutral states |
-| `secondary` | <Swatch size="inline" bg="gray-300" /> `var(--bs-gray-300)` | Less prominent secondary actions |
+| `inverse` | <Swatch size="inline" bg="gray-900" /> `var(--bs-gray-900)` | High contrast by inverting foreground and background |
+| `secondary` | <Swatch size="inline" bg="gray-300" /> `var(--bs-gray-300)` | Less prominent actions and states |
</BsTable>
And within each semantic theme color, you'll find the following keys, most of which are color-mode adaptive:
| --- | --- |
| `base` | The default color value for the semantic color |
| `text` | Accessible text color (against body, plus `subtle` and `muted` color tokens) |
+| `text-emphasis` | Emphasized text color for use with `muted` background tokens |
| `bg` | For solid colored backgrounds with high contrast |
| `bg-subtle` | Lowest contrast backgrounds, usually paired with `text` key for text color |
| `bg-muted` | Lower contrast backgrounds, often used for disabled states |
Every token is available as a CSS variable, and most are then consumed by our utilities and components. So for the `primary` color, you have the following colors:
-<div class="grid gap-0" style={{gridTemplateColumns: 'repeat(8, 1fr)', gap: '8px', minWidth: '0'}}>
+<div class="grid gap-0" style={{gridTemplateColumns: 'repeat(9, 1fr)', gap: '8px', minWidth: '0'}}>
{getData('theme-colors').map((color) => {
return (
<div class="d-contents grid-full">
})}
</div>
-## Theme `fg` and `bg`
+### Pairings
-Theme foreground and background tokens are defined in their respective `$theme-fgs` and `$theme-bgs` Sass maps. These maps are used to generate color mode adaptive `color` and `background-color` values that are then consumed by our utilities and components. You'll find these values in the `_theme.scss` file.
+Not all colors can be used for all purposes due to accessibility, color contrast, and general aesthetic considerations. Here are some recommended pairings.
-Theme backgrounds include the following semantic colors:
+- `contrast` work best with `bg`
+- `text` works best with `subtle`
+- `text-emphasis` works best with `muted`
+- `border` works best with `subtle`, but can be used with `muted`
+
+<Example code={`<div class="theme-primary vstack gap-3">
+ <div style="color: var(--bs-theme-contrast); background: var(--bs-theme-bg);" class="p-3 rounded-3">
+ Example element with theme color
+ </div>
+ <div style="color: var(--bs-theme-text-emphasis); background: var(--bs-theme-bg-muted); border: 1px solid var(--bs-theme-border);" class="p-3 rounded-3">
+ Example element with theme color
+ </div>
+ <div style="color: var(--bs-theme-text); background: var(--bs-theme-bg-subtle); border: 1px solid var(--bs-theme-border);" class="p-3 rounded-3">
+ Example element with theme color
+ </div>
+ </div>`} />
+
+## Layer colors
+
+Color tokens that are used for foreground, background, and border colors are called **theme layer colors** in Bootstrap. These layer colors are configured outside the `$new-theme-colors` Sass map in their own respective Sass maps as they have more nuanced theming use cases.
+
+Tokens for these three themes are defined in the `$theme-fgs`, `$theme-bgs`, and `$theme-borders` Sass maps. These maps are used to generate color mode adaptive `color`, `background-color`, and `border-color` values that are then consumed by our utilities and components. You'll find these values in the `_theme.scss` file.
+
+### Background
+
+Theme backgrounds include several practical and semantic color options.
<BsTable>
| Background | Default value | Description |
| --- | --- | --- |
-| `null` | <Swatch bg="bg" size="inline" /> `var(--bs-white)` | Default background color |
-| `1` | <Swatch bg="bg-1" size="inline" /> `var(--bs-gray-025)` | Lowest contrast background color |
-| `2` | <Swatch bg="bg-2" size="inline" /> `var(--bs-gray-050)` | Lower contrast background color |
-| `3` | <Swatch bg="bg-3" size="inline" /> `var(--bs-gray-100)` | Medium contrast background color, typically used for disabled states |
-| `white` | <Swatch bg="bg-white" size="inline" /> `var(--bs-white)` | Pure white background color |
-| `black` | <Swatch bg="bg-black" size="inline" /> `var(--bs-black)` | Pure black background color |
-| `transparent` | <Swatch bg="bg-transparent" size="inline" /> `transparent` | Transparent background color |
+| `body` | <Swatch bg="bg-body" size="inline" /> | Default background color |
+| `secondary` | <Swatch bg="bg-1" size="inline" /> | Lowest contrast background color |
+| `subtle` | <Swatch bg="bg-2" size="inline" /> | Lower contrast background color |
+| `muted` | <Swatch bg="bg-3" size="inline" /> | Medium contrast background color, typically used for disabled states |
+| `white` | <Swatch bg="bg-white" size="inline" /> | Pure white background color |
+| `black` | <Swatch bg="bg-black" size="inline" /> | Pure black background color |
+| `transparent` | <Swatch bg="bg-transparent" size="inline" /> | Transparent background color |
| `inherit` |`inherit` | Inherited background color |
</BsTable>
+### Foreground
+
+Almost all those options are also available for foreground text colors.
+
<BsTable>
| Foreground | Default value | Description |
| --- | --- | --- |
-| `null` | <Swatch bg="fg" size="inline" /> `var(--bs-gray-900)` | Default foreground color |
-| `1` | <Swatch bg="fg-1" size="inline" /> `var(--bs-gray-800)` | Lowest contrast foreground color |
-| `2` | <Swatch bg="fg-2" size="inline" /> `var(--bs-gray-700)` | Lower contrast foreground color |
-| `3` | <Swatch bg="fg-3" size="inline" /> `var(--bs-gray-600)` | Medium contrast foreground color |
-| `white` | <Swatch bg="fg-white" size="inline" /> `var(--bs-white)` | Pure white foreground color |
-| `black` | <Swatch bg="fg-black" size="inline" /> `var(--bs-black)` | Pure black foreground color |
-| `transparent` | <Swatch bg="fg-transparent" size="inline" /> `transparent` | Transparent foreground color |
+| `body` | <Swatch bg="fg-body" size="inline" /> | Default foreground color |
+| `secondary` | <Swatch bg="fg-1" size="inline" /> | Lowest contrast foreground color |
+| `subtle` | <Swatch bg="fg-2" size="inline" /> | Lower contrast foreground color |
+| `muted` | <Swatch bg="fg-3" size="inline" /> | Medium contrast foreground color |
+| `white` | <Swatch bg="fg-white" size="inline" /> | Pure white foreground color |
+| `black` | <Swatch bg="fg-black" size="inline" /> | Pure black foreground color |
| `inherit` | `inherit` | Inherited foreground color |
</BsTable>
-### Suggested pairings
+### Border
-Not all foreground colors are appropriate for all background colors. To maintain color contrast for accessibility, here are some recommended pairings.
+Border colors have similar levels, but different naming.
-<div class="d-flex gap-3 w-100">
- <div class="d-flex flex-column gap-2 w-100">
- <Swatch bg="bg" fg="fg" size="large" contrast="15.71" contrastDark="14.59">fg on bg</Swatch>
- <Swatch bg="bg" fg="fg-1" size="large" contrast="12.50" contrastDark="10.77">fg-1 on bg</Swatch>
- <Swatch bg="bg" fg="fg-2" size="large" contrast="9.54" contrastDark="7.76">fg-2 on bg</Swatch>
- <Swatch bg="bg" fg="fg-3" size="large" contrast="7.01" contrastDark="6.32">fg-3 on bg</Swatch>
- </div>
- <div class="d-flex flex-column gap-2 w-100">
- <Swatch bg="bg-1" fg="fg" size="large">fg on bg-1</Swatch>
- <Swatch bg="bg-1" fg="fg-1" size="large">fg-1 on bg-1</Swatch>
- <Swatch bg="bg-1" fg="fg-2" size="large">fg-2 on bg-1</Swatch>
- <Swatch bg="bg-1" fg="fg-3" size="large">fg-3 on bg-1</Swatch>
- </div>
- <div class="d-flex flex-column gap-2 w-100">
- <Swatch bg="bg-2" fg="fg" size="large">fg on bg-2</Swatch>
- <Swatch bg="bg-2" fg="fg-1" size="large">fg-1 on bg-2</Swatch>
- <Swatch bg="bg-2" fg="fg-2" size="large">fg-2 on bg-2</Swatch>
- <Swatch bg="bg-2" fg="fg-3" size="large">fg-3 on bg-2</Swatch>
- </div>
- <div class="d-flex flex-column gap-2 w-100">
- <Swatch bg="bg-3" fg="fg" size="large">fg on bg-3</Swatch>
- <Swatch bg="bg-3" fg="fg-1" size="large">fg-1 on bg-3</Swatch>
- <Swatch bg="bg-3" fg="fg-2" size="large">fg-2 on bg-3</Swatch>
- <Swatch bg="bg-3" fg="fg-3" size="large">fg-3 on bg-3</Swatch>
- </div>
-</div>
+<BsTable>
+| Border | Default value | Description |
+| --- | --- | --- |
+| `null` | <Swatch bg="border" size="inline" /> | Default border color |
+| `muted` | <Swatch bg="border-muted" size="inline" /> | Muted border color |
+| `subtle` | <Swatch bg="border-subtle" size="inline" /> | Subtle border color |
+| `emphasized` | <Swatch bg="border-emphasized" size="inline" /> | Emphasized border color |
+</BsTable>
-## Theme foregrounds
+### Examples
-Theme foregrounds are defined in the `$theme-fgs` Sass map. This map is used to generate our theme foreground values. You'll find these values in the `_theme.scss` file. These are where we define our design tokens for Bootstrap, across both light and dark color modes.
+Not all colors can be used for all purposes due to accessibility, color contrast, and general aesthetic considerations. Here are some recommended pairings.
-Theme foregrounds include the following semantic colors:
+- `color-body` works with all `bg` colors
+- `color-1` works with `bg-body`, `bg-1`, `bg-2`, and `bg-3`
+- `color-2` works with `bg-body`, `bg-1`, and `bg-2`
+- `color-3` works with `bg-body`, `bg-1`
-<BsTable>
-| Foreground | Default value | Description |
-| --- | --- | --- |
-| `null` | `var(--bs-gray-900)` | Default foreground color |
-| `1` | `var(--bs-gray-800)` | Lowest contrast foreground color |
-| `2` | `var(--bs-gray-700)` | Lower contrast foreground color |
-| `3` | `var(--bs-gray-600)` | Medium contrast foreground color |
-</BsTable>
+Here are some examples showing them together. Note
+
+<Example code={`<div class="vstack gap-3">
+ <div class="p-3 rounded-3 bg-body color-body border">
+ color-body on bg-body
+ </div>
+ <div class="p-3 rounded-3 bg-1 color-3 border">
+ color-3 on bg-1
+ </div>
+ <div class="p-3 rounded-3 bg-2 color-2 border">
+ color-2 on bg-2
+ </div>
+ <div class="p-3 rounded-3 bg-3 color-1 border">
+ color-1 on bg-3
+ </div>
+ </div>`} />
+
+## Theme utility classes
+
+We generate theme utility classes from the `$new-theme-colors` Sass map that make all theme color tokens available as CSS variables. We use these in our component variants to allow for quick theming with a single, global class. This requires components to support theme colors, and not every component does.
+
+With theme utilities, you can apply a theme color to an element with a single class.
+
+<Example class="vstack gap-3" code={`<div class="alert theme-primary">Primary alert</div>
+ <div>
+ <button type="button" class="btn btn-solid theme-primary">Primary button</button>
+ <button type="button" class="btn btn-outline theme-primary">Primary outline button</button>
+ <button type="button" class="btn btn-subtle theme-primary">Primary subtle button</button>
+ <button type="button" class="btn btn-text theme-primary">Primary text button</button>
+ </div>
+ <div>
+ <span class="badge theme-primary">Primary badge</span>
+ <span class="badge badge-subtle theme-primary">Primary subtle badge</span>
+ </div>`} />
+
+And you can apply a theme color utility to a container and any theme-aware children will inherit the theme color.
+
+<Example code={`<div class="vstack gap-3 theme-primary">
+ <div class="alert">Primary alert</div>
+ <div>
+ <button type="button" class="btn btn-solid">Primary button</button>
+ <button type="button" class="btn btn-outline">Primary outline button</button>
+ <button type="button" class="btn btn-subtle">Primary subtle button</button>
+ <button type="button" class="btn btn-text">Primary text button</button>
+ </div>
+ <div>
+ <span class="badge">Primary badge</span>
+ <span class="badge badge-subtle">Primary subtle badge</span>
+ </div>
+ </div>`} />
+
+This also means you can override a container's theme color with another theme color on specific components.
+
+<Example code={`<div class="vstack gap-3 theme-primary">
+ <div class="alert">Primary alert</div>
+ <div>
+ <button type="button" class="btn btn-solid theme-emphasis">Emphasis button</button>
+ <button type="button" class="btn btn-outline">Primary outline button</button>
+ <button type="button" class="btn btn-subtle theme-danger">Danger subtle button</button>
+ <button type="button" class="btn btn-text">Primary text button</button>
+ </div>
+ <div>
+ <span class="badge theme-success">Success badge</span>
+ <span class="badge badge-subtle">Primary subtle badge</span>
+ </div>
+ </div>`} />
-<div class="grid gap-0" style={{gridTemplateColumns: 'repeat(8, 1fr)', gap: '8px', minWidth: '0'}}>
- {themeFgs.map((color) => {
- return (
- <div>
- <Swatch color={`fg-${color}`} size="large" />
- <div class="text-center color-3">{color}</div>
- </div>
- )
- })}
-</div>
## Theme Sass map
)
}
<a
- class="btn btn-secondary-text btn-sm"
+ class="btn btn-subtle btn-sm theme-secondary"
href={`${getConfig().repo}/blob/v${getConfig().current_version}/site/src/content/docs/${id}`}
title="View and edit this file on GitHub"
target="_blank"
<slot />
<nav class="bd-links-nav py-5 mt-5 border-top">
- <div class="grid">
- <div class="col-6">
- {
- prevPage && (
- <a href={prevPage.url} class="d-block p-3 text-decoration-none rounded-3">
- <div class="text-secondary small">Previous</div>
- <div class="fw-semibold">← {prevPage.title}</div>
- <div class="text-secondary small">{prevPage.groupTitle}</div>
- </a>
- )
- }
- </div>
- <div class="col-6">
- {
- nextPage && (
- <a href={nextPage.url} class="d-block p-3 text-decoration-none text-end rounded-3">
- <div class="text-secondary small">Next</div>
- <div class="fw-semibold">{nextPage.title} →</div>
- <div class="text-secondary small">{nextPage.groupTitle}</div>
- </a>
- )
- }
- </div>
+ <div class="d-flex flex-column flex-md-row justify-content-between">
+ {
+ prevPage && (
+ <a href={prevPage.url} class="d-block p-3 text-decoration-none rounded-3">
+ <div class="text-secondary small">← Previous</div>
+ <div class="fw-semibold">{prevPage.title}</div>
+ <div class="text-secondary small">{prevPage.groupTitle}</div>
+ </a>
+ )
+ }
+ {
+ nextPage && (
+ <a href={nextPage.url} class="d-block p-3 text-decoration-none text-end bg-1 rounded-3">
+ <div class="color-3">Next →</div>
+ <div class="fs-5 fw-semibold">{nextPage.title}</div>
+ <div class="color-3">{nextPage.groupTitle}</div>
+ </a>
+ )
+ }
</div>
</nav>
</div>
border: 1px solid color-mix(in srgb, var(--bd-violet) 30%, transparent);
}
+ .bd-example-buttons {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: .5rem;
+ justify-content: start;
+ }
+
// // Grid mixins
// .example-container {
// width: 800px;
min-height: 15rem;
> div {
- color: var(--bs-body-bg);
+ color: var(--bs-bg-body);
background-color: var(--bd-violet);
border: 1px solid var(--bd-purple);
.bd-masthead {
padding: 3rem 0;
// stylelint-disable
- background-image: linear-gradient(180deg, color-mix(in srgb, var(--bs-body-bg) 1%, transparent), var(--bs-body-bg) 85%),
+ background-image: linear-gradient(180deg, color-mix(in srgb, var(--bs-bg-body) 1%, transparent), var(--bs-bg-body) 85%),
radial-gradient(ellipse at top left, color-mix(in srgb, var(--bs-blue-500) 50%, transparent), transparent 50%),
radial-gradient(ellipse at top right, color-mix(in srgb, var(--bd-accent) 50%, transparent), transparent 50%),
radial-gradient(ellipse at center right, color-mix(in srgb, var(--bd-violet) 50%, transparent), transparent 50%),
mix-blend-mode: darken;
svg {
- filter: drop-shadow(0 1px 1px var(--bs-body-bg));
+ filter: drop-shadow(0 1px 1px var(--bs-bg-body));
}
}
}
@include media-breakpoint-down(md) {
- color: var(--bs-body-color);
+ color: var(--bs-color-body);
border: 1px solid var(--bs-border-color);
@include border-radius(var(--bs-border-radius));
&:active,
&[aria-expanded="true"] {
color: var(--bd-violet);
- background-color: var(--bs-body-bg);
+ background-color: var(--bs-bg-body);
border-color: var(--bd-violet);
}
@include media-breakpoint-down(md) {
nav {
padding: 1.25rem 1.25rem 1.25rem 1rem;
- background-color: var(--bs-tertiary-bg);
+ background-color: var(--bs-bg-subtle);
border: 1px solid var(--bs-border-color);
@include border-radius(var(--bs-border-radius));
}