├── .github └── workflows │ └── main.yml ├── .gitignore ├── Gemfile ├── LICENSE.txt ├── _config.yml ├── _includes ├── alert.md ├── footer.md ├── head.html ├── header.md └── nav.md ├── _layouts ├── page.html └── redirect.html ├── _sass ├── bootstrap │ ├── LICENSE │ └── scss │ │ ├── _accordion.scss │ │ ├── _alert.scss │ │ ├── _badge.scss │ │ ├── _breadcrumb.scss │ │ ├── _button-group.scss │ │ ├── _buttons.scss │ │ ├── _card.scss │ │ ├── _carousel.scss │ │ ├── _close.scss │ │ ├── _containers.scss │ │ ├── _dropdown.scss │ │ ├── _forms.scss │ │ ├── _functions.scss │ │ ├── _grid.scss │ │ ├── _helpers.scss │ │ ├── _images.scss │ │ ├── _list-group.scss │ │ ├── _maps.scss │ │ ├── _mixins.scss │ │ ├── _modal.scss │ │ ├── _nav.scss │ │ ├── _navbar.scss │ │ ├── _offcanvas.scss │ │ ├── _pagination.scss │ │ ├── _placeholders.scss │ │ ├── _popover.scss │ │ ├── _progress.scss │ │ ├── _reboot.scss │ │ ├── _root.scss │ │ ├── _spinners.scss │ │ ├── _tables.scss │ │ ├── _toasts.scss │ │ ├── _tooltip.scss │ │ ├── _transitions.scss │ │ ├── _type.scss │ │ ├── _utilities.scss │ │ ├── _variables-dark.scss │ │ ├── _variables.scss │ │ ├── bootstrap-grid.scss │ │ ├── bootstrap-reboot.scss │ │ ├── bootstrap-utilities.scss │ │ ├── bootstrap.scss │ │ ├── forms │ │ ├── _floating-labels.scss │ │ ├── _form-check.scss │ │ ├── _form-control.scss │ │ ├── _form-range.scss │ │ ├── _form-select.scss │ │ ├── _form-text.scss │ │ ├── _input-group.scss │ │ ├── _labels.scss │ │ └── _validation.scss │ │ ├── helpers │ │ ├── _clearfix.scss │ │ ├── _color-bg.scss │ │ ├── _colored-links.scss │ │ ├── _focus-ring.scss │ │ ├── _icon-link.scss │ │ ├── _position.scss │ │ ├── _ratio.scss │ │ ├── _stacks.scss │ │ ├── _stretched-link.scss │ │ ├── _text-truncation.scss │ │ ├── _visually-hidden.scss │ │ └── _vr.scss │ │ ├── mixins │ │ ├── _alert.scss │ │ ├── _backdrop.scss │ │ ├── _banner.scss │ │ ├── _border-radius.scss │ │ ├── _box-shadow.scss │ │ ├── _breakpoints.scss │ │ ├── _buttons.scss │ │ ├── _caret.scss │ │ ├── _clearfix.scss │ │ ├── _color-mode.scss │ │ ├── _color-scheme.scss │ │ ├── _container.scss │ │ ├── _deprecate.scss │ │ ├── _forms.scss │ │ ├── _gradients.scss │ │ ├── _grid.scss │ │ ├── _image.scss │ │ ├── _list-group.scss │ │ ├── _lists.scss │ │ ├── _pagination.scss │ │ ├── _reset-text.scss │ │ ├── _resize.scss │ │ ├── _table-variants.scss │ │ ├── _text-truncate.scss │ │ ├── _transition.scss │ │ ├── _utilities.scss │ │ └── _visually-hidden.scss │ │ ├── utilities │ │ └── _api.scss │ │ └── vendor │ │ └── _rfs.scss ├── default.scss ├── github-dark.scss ├── jekyll-theme-cs50.scss └── page.scss ├── assets ├── @fortawesome │ └── fontawesome-free │ │ ├── css │ │ └── all.min.css │ │ └── webfonts │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff2 │ │ ├── fa-v4compatibility.ttf │ │ └── fa-v4compatibility.woff2 ├── algolia-min.css ├── algoliasearch │ └── dist │ │ └── algoliasearch.umd.js ├── algoliasearchLite.min.js ├── bootstrap-table │ ├── LICENSE │ └── dist │ │ ├── bootstrap-table.min.css │ │ ├── bootstrap-table.min.js │ │ └── extensions │ │ └── mobile │ │ └── bootstrap-table-mobile.min.js ├── bootstrap │ ├── LICENSE │ └── dist │ │ └── js │ │ ├── bootstrap.bundle.min.js │ │ └── bootstrap.bundle.min.js.map ├── iframe-resizer │ ├── LICENSE │ └── js │ │ └── iframeResizer.min.js ├── instantsearch.js │ ├── LICENSE │ └── dist │ │ ├── instantsearch.production.min.js │ │ └── instantsearch.production.min.js.map ├── instantsearch.production.min.js ├── intersection-observer │ ├── intersection-observer.js │ └── package.json ├── jekyll-theme-cs50.js ├── jquery │ ├── LICENSE.txt │ └── dist │ │ └── jquery.min.js ├── luxon │ ├── LICENSE.md │ └── build │ │ └── global │ │ └── luxon.min.js ├── mathjax │ ├── LICENSE │ └── es5 │ │ ├── output │ │ └── chtml │ │ │ └── fonts │ │ │ └── woff-v2 │ │ │ ├── MathJax_AMS-Regular.woff │ │ │ ├── MathJax_Calligraphic-Bold.woff │ │ │ ├── MathJax_Calligraphic-Regular.woff │ │ │ ├── MathJax_Fraktur-Bold.woff │ │ │ ├── MathJax_Fraktur-Regular.woff │ │ │ ├── MathJax_Main-Bold.woff │ │ │ ├── MathJax_Main-Italic.woff │ │ │ ├── MathJax_Main-Regular.woff │ │ │ ├── MathJax_Math-BoldItalic.woff │ │ │ ├── MathJax_Math-Italic.woff │ │ │ ├── MathJax_Math-Regular.woff │ │ │ ├── MathJax_SansSerif-Bold.woff │ │ │ ├── MathJax_SansSerif-Italic.woff │ │ │ ├── MathJax_SansSerif-Regular.woff │ │ │ ├── MathJax_Script-Regular.woff │ │ │ ├── MathJax_Size1-Regular.woff │ │ │ ├── MathJax_Size2-Regular.woff │ │ │ ├── MathJax_Size3-Regular.woff │ │ │ ├── MathJax_Size4-Regular.woff │ │ │ ├── MathJax_Typewriter-Regular.woff │ │ │ ├── MathJax_Vector-Bold.woff │ │ │ ├── MathJax_Vector-Regular.woff │ │ │ └── MathJax_Zero.woff │ │ └── tex-chtml.js ├── mermaid.min.js ├── mermaid │ ├── dist │ │ └── mermaid.min.js │ └── package.json ├── page.js ├── page.scss ├── popper.js │ └── dist │ │ └── umd │ │ └── popper.min.js ├── reset-min.css ├── scratchblocks.min.js ├── scratchblocks.min.js.map ├── twemoji │ ├── LICENSE │ └── dist │ │ └── twemoji.min.js └── vanilla-lazyload │ ├── LICENSE │ └── dist │ └── lazyload.min.js ├── jekyll-theme-cs50.gemspec ├── lib ├── jekyll-theme-cs50.rb ├── jekyll-theme-cs50 │ └── constants.rb └── liquid-tag-parser.rb ├── package-lock.json └── package.json /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: push 2 | jobs: 3 | deploy: 4 | runs-on: ubuntu-latest 5 | steps: 6 | - name: Re-deploy dependents 7 | if: ${{ github.ref == 'refs/heads/develop' }} 8 | uses: actions/github-script@v7 9 | with: 10 | github-token: ${{ secrets.DEPLOY50_PAT }} 11 | script: | 12 | const dependents = [ 13 | ['ai', '2024/x'], 14 | ['ai', '2025/spring'], 15 | ['ai', '2025/summer'], 16 | ['ap', '2024'], 17 | ['beyond', '2019/x'], 18 | ['business', '2017/x'], 19 | ['business', '2025/spring'], 20 | ['business', '2025/summer'], 21 | ['cs50.tf', 'main'], 22 | ['cybersecurity', '2023/x'], 23 | ['cybersecurity', '2025/spring'], 24 | ['cybersecurity', '2025/summer'], 25 | ['games', '2018/x'], 26 | ['harvard', '2024/x'], 27 | ['harvard', '2025/spring'], 28 | ['harvard', '2025/summer'], 29 | ['hbap.io', 'main'], 30 | ['hls', '2025/winter'], 31 | ['law', '2019/x'], 32 | ['mobile', '2018/x'], 33 | ['python', '2022/x'], 34 | ['r', '2024/x'], 35 | ['scratch', '2024/x'], 36 | ['sql', '2024/x'], 37 | ['sql', '2025/spring'], 38 | ['technology', '2017/x'], 39 | ['web', '2020/x'], 40 | ['web', '2025/spring'] 41 | ]; 42 | for (let dependent of dependents) { 43 | await github.rest.actions.createWorkflowDispatch({ 44 | owner: 'cs50', 45 | repo: dependent[0], 46 | workflow_id: 'main.yml', 47 | ref: dependent[1] 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !/.github/ 3 | !.gitignore 4 | 5 | *.gem 6 | 7 | # https://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ 8 | Gemfile.lock 9 | 10 | _sass/bootstrap/* 11 | !_sass/bootstrap/LICENSE 12 | !_sass/bootstrap/scss/ 13 | 14 | _sass/primer-markdown/* 15 | !_sass/primer-markdown/LICENSE 16 | !_sass/primer-markdown/build/ 17 | _sass/primer-markdown/build/* 18 | !_sass/primer-markdown/build/build.scss 19 | 20 | _site/ 21 | 22 | assets/algoliasearch/* 23 | !assets/algoliasearch/dist/ 24 | assets/algoliasearch/dist/* 25 | !assets/algoliasearch/dist/algoliasearch.umd.js 26 | 27 | assets/bootstrap/* 28 | !assets/bootstrap/LICENSE 29 | !assets/bootstrap/dist/ 30 | assets/bootstrap/dist/* 31 | !assets/bootstrap/dist/js/ 32 | assets/bootstrap/dist/js/* 33 | !assets/bootstrap/dist/js/bootstrap.bundle.min.js 34 | !assets/bootstrap/dist/js/bootstrap.bundle.min.js.map 35 | 36 | assets/bootstrap-table/* 37 | !assets/bootstrap-table/LICENSE 38 | !assets/bootstrap-table/dist/ 39 | assets/bootstrap-table/dist/* 40 | !assets/bootstrap-table/dist/bootstrap-table.min.css 41 | !assets/bootstrap-table/dist/bootstrap-table.min.js 42 | !assets/bootstrap-table/dist/extensions/ 43 | assets/bootstrap-table/dist/extensions/* 44 | !assets/bootstrap-table/dist/extensions/mobile/ 45 | assets/bootstrap-table/dist/extensions/mobile/* 46 | !assets/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile.min.js 47 | 48 | assets/@fortawesome/* 49 | !assets/@fortawesome/fontawesome-free/ 50 | assets/@fortawesome/fontawesome-free/* 51 | !assets/@fortawesome/fontawesome-free/css/ 52 | assets/@fortawesome/fontawesome-free/css/* 53 | !assets/@fortawesome/fontawesome-free/css/all.min.css 54 | !assets/@fortawesome/fontawesome-free/webfonts/ 55 | 56 | assets/iframe-resizer/* 57 | !assets/iframe-resizer/LICENSE 58 | !assets/iframe-resizer/js/ 59 | assets/iframe-resizer/js/* 60 | !assets/iframe-resizer/js/iframeResizer.min.js 61 | 62 | assets/instantsearch.js/* 63 | !assets/instantsearch.js/LICENSE 64 | !assets/instantsearch.js/dist/ 65 | assets/instantsearch.js/dist/* 66 | !assets/instantsearch.js/dist/instantsearch.production.min.js 67 | !assets/instantsearch.js/dist/instantsearch.production.min.js.map 68 | 69 | assets/intersection-observer/* 70 | !assets/intersection-observer/intersection-observer.js 71 | !assets/intersection-observer/package.json 72 | 73 | assets/jquery/* 74 | !assets/jquery/LICENSE.txt 75 | !assets/jquery/dist/ 76 | assets/jquery/dist/* 77 | !assets/jquery/dist/jquery.min.js 78 | 79 | assets/luxon/* 80 | !assets/luxon/LICENSE.md 81 | !assets/luxon/build/ 82 | assets/luxon/build/* 83 | !assets/luxon/build/global/ 84 | assets/luxon/build/global/* 85 | !assets/luxon/build/global/luxon.min.js 86 | 87 | assets/mathjax/* 88 | !assets/mathjax/LICENSE 89 | !assets/mathjax/es5/ 90 | assets/mathjax/es5/* 91 | !assets/mathjax/es5/tex-chtml.js 92 | !assets/mathjax/es5/output/ 93 | assets/mathjax/es5/output/* 94 | !assets/mathjax/es5/output/chtml/ 95 | assets/mathjax/es5/output/chtml/* 96 | !assets/mathjax/es5/output/chtml/fonts/ 97 | assets/mathjax/es5/output/chtml/fonts/* 98 | !assets/mathjax/es5/output/chtml/fonts/woff-v2/ 99 | assets/mathjax/es5/output/chtml/fonts/woff-v2/* 100 | !assets/mathjax/es5/output/chtml/fonts/woff-v2/*.woff 101 | 102 | assets/mermaid/* 103 | !assets/mermaid/package.json 104 | !assets/mermaid/dist/ 105 | assets/mermaid/dist/* 106 | !assets/mermaid/dist/mermaid.min.js 107 | 108 | assets/popper.js/* 109 | !assets/popper.js/dist/ 110 | assets/popper.js/dist/* 111 | !assets/popper.js/dist/umd/ 112 | assets/popper.js/dist/umd/* 113 | !assets/popper.js/dist/umd/popper.min.js 114 | 115 | assets/twemoji/* 116 | !assets/twemoji/LICENSE 117 | !assets/twemoji/dist/ 118 | assets/twemoji/dist/* 119 | !assets/twemoji/dist/twemoji.min.js 120 | 121 | assets/vanilla-lazyload/* 122 | !assets/vanilla-lazyload/LICENSE 123 | !assets/vanilla-lazyload/dist/ 124 | assets/vanilla-lazyload/dist/* 125 | !assets/vanilla-lazyload/dist/lazyload.min.js 126 | 127 | node_modules/ 128 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | defaults: 2 | - 3 | scope: 4 | path: "" 5 | values: 6 | layout: "page" 7 | 8 | sass: 9 | load_paths: 10 | - _sass 11 | - _sass/node_modules 12 | -------------------------------------------------------------------------------- /_includes/alert.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cs50/jekyll-theme-cs50/dc782cc9bc8617b0fa4348015c89849407eff650/_includes/alert.md -------------------------------------------------------------------------------- /_includes/footer.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cs50/jekyll-theme-cs50/dc782cc9bc8617b0fa4348015c89849407eff650/_includes/footer.md -------------------------------------------------------------------------------- /_includes/head.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cs50/jekyll-theme-cs50/dc782cc9bc8617b0fa4348015c89849407eff650/_includes/head.html -------------------------------------------------------------------------------- /_includes/header.md: -------------------------------------------------------------------------------- 1 | # [{{ site.cs50.title }}](/) 2 | -------------------------------------------------------------------------------- /_includes/nav.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cs50/jekyll-theme-cs50/dc782cc9bc8617b0fa4348015c89849407eff650/_includes/nav.md -------------------------------------------------------------------------------- /_layouts/redirect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /_sass/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2025 The Bootstrap Authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_accordion.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .accordion { 6 | // scss-docs-start accordion-css-vars 7 | --#{$prefix}accordion-color: #{$accordion-color}; 8 | --#{$prefix}accordion-bg: #{$accordion-bg}; 9 | --#{$prefix}accordion-transition: #{$accordion-transition}; 10 | --#{$prefix}accordion-border-color: #{$accordion-border-color}; 11 | --#{$prefix}accordion-border-width: #{$accordion-border-width}; 12 | --#{$prefix}accordion-border-radius: #{$accordion-border-radius}; 13 | --#{$prefix}accordion-inner-border-radius: #{$accordion-inner-border-radius}; 14 | --#{$prefix}accordion-btn-padding-x: #{$accordion-button-padding-x}; 15 | --#{$prefix}accordion-btn-padding-y: #{$accordion-button-padding-y}; 16 | --#{$prefix}accordion-btn-color: #{$accordion-button-color}; 17 | --#{$prefix}accordion-btn-bg: #{$accordion-button-bg}; 18 | --#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)}; 19 | --#{$prefix}accordion-btn-icon-width: #{$accordion-icon-width}; 20 | --#{$prefix}accordion-btn-icon-transform: #{$accordion-icon-transform}; 21 | --#{$prefix}accordion-btn-icon-transition: #{$accordion-icon-transition}; 22 | --#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon)}; 23 | --#{$prefix}accordion-btn-focus-box-shadow: #{$accordion-button-focus-box-shadow}; 24 | --#{$prefix}accordion-body-padding-x: #{$accordion-body-padding-x}; 25 | --#{$prefix}accordion-body-padding-y: #{$accordion-body-padding-y}; 26 | --#{$prefix}accordion-active-color: #{$accordion-button-active-color}; 27 | --#{$prefix}accordion-active-bg: #{$accordion-button-active-bg}; 28 | // scss-docs-end accordion-css-vars 29 | } 30 | 31 | .accordion-button { 32 | position: relative; 33 | display: flex; 34 | align-items: center; 35 | width: 100%; 36 | padding: var(--#{$prefix}accordion-btn-padding-y) var(--#{$prefix}accordion-btn-padding-x); 37 | @include font-size($font-size-base); 38 | color: var(--#{$prefix}accordion-btn-color); 39 | text-align: left; // Reset button style 40 | background-color: var(--#{$prefix}accordion-btn-bg); 41 | border: 0; 42 | @include border-radius(0); 43 | overflow-anchor: none; 44 | @include transition(var(--#{$prefix}accordion-transition)); 45 | 46 | &:not(.collapsed) { 47 | color: var(--#{$prefix}accordion-active-color); 48 | background-color: var(--#{$prefix}accordion-active-bg); 49 | box-shadow: inset 0 calc(-1 * var(--#{$prefix}accordion-border-width)) 0 var(--#{$prefix}accordion-border-color); // stylelint-disable-line function-disallowed-list 50 | 51 | &::after { 52 | background-image: var(--#{$prefix}accordion-btn-active-icon); 53 | transform: var(--#{$prefix}accordion-btn-icon-transform); 54 | } 55 | } 56 | 57 | // Accordion icon 58 | &::after { 59 | flex-shrink: 0; 60 | width: var(--#{$prefix}accordion-btn-icon-width); 61 | height: var(--#{$prefix}accordion-btn-icon-width); 62 | margin-left: auto; 63 | content: ""; 64 | background-image: var(--#{$prefix}accordion-btn-icon); 65 | background-repeat: no-repeat; 66 | background-size: var(--#{$prefix}accordion-btn-icon-width); 67 | @include transition(var(--#{$prefix}accordion-btn-icon-transition)); 68 | } 69 | 70 | &:hover { 71 | z-index: 2; 72 | } 73 | 74 | &:focus { 75 | z-index: 3; 76 | outline: 0; 77 | box-shadow: var(--#{$prefix}accordion-btn-focus-box-shadow); 78 | } 79 | } 80 | 81 | .accordion-header { 82 | margin-bottom: 0; 83 | } 84 | 85 | .accordion-item { 86 | color: var(--#{$prefix}accordion-color); 87 | background-color: var(--#{$prefix}accordion-bg); 88 | border: var(--#{$prefix}accordion-border-width) solid var(--#{$prefix}accordion-border-color); 89 | 90 | &:first-of-type { 91 | @include border-top-radius(var(--#{$prefix}accordion-border-radius)); 92 | 93 | > .accordion-header .accordion-button { 94 | @include border-top-radius(var(--#{$prefix}accordion-inner-border-radius)); 95 | } 96 | } 97 | 98 | &:not(:first-of-type) { 99 | border-top: 0; 100 | } 101 | 102 | // Only set a border-radius on the last item if the accordion is collapsed 103 | &:last-of-type { 104 | @include border-bottom-radius(var(--#{$prefix}accordion-border-radius)); 105 | 106 | > .accordion-header .accordion-button { 107 | &.collapsed { 108 | @include border-bottom-radius(var(--#{$prefix}accordion-inner-border-radius)); 109 | } 110 | } 111 | 112 | > .accordion-collapse { 113 | @include border-bottom-radius(var(--#{$prefix}accordion-border-radius)); 114 | } 115 | } 116 | } 117 | 118 | .accordion-body { 119 | padding: var(--#{$prefix}accordion-body-padding-y) var(--#{$prefix}accordion-body-padding-x); 120 | } 121 | 122 | 123 | // Flush accordion items 124 | // 125 | // Remove borders and border-radius to keep accordion items edge-to-edge. 126 | 127 | .accordion-flush { 128 | > .accordion-item { 129 | border-right: 0; 130 | border-left: 0; 131 | @include border-radius(0); 132 | 133 | &:first-child { border-top: 0; } 134 | &:last-child { border-bottom: 0; } 135 | 136 | // stylelint-disable selector-max-class 137 | > .accordion-collapse, 138 | > .accordion-header .accordion-button, 139 | > .accordion-header .accordion-button.collapsed { 140 | @include border-radius(0); 141 | } 142 | // stylelint-enable selector-max-class 143 | } 144 | } 145 | 146 | @if $enable-dark-mode { 147 | @include color-mode(dark) { 148 | .accordion-button::after { 149 | --#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon-dark)}; 150 | --#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon-dark)}; 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_alert.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .alert { 6 | // scss-docs-start alert-css-vars 7 | --#{$prefix}alert-bg: transparent; 8 | --#{$prefix}alert-padding-x: #{$alert-padding-x}; 9 | --#{$prefix}alert-padding-y: #{$alert-padding-y}; 10 | --#{$prefix}alert-margin-bottom: #{$alert-margin-bottom}; 11 | --#{$prefix}alert-color: inherit; 12 | --#{$prefix}alert-border-color: transparent; 13 | --#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color); 14 | --#{$prefix}alert-border-radius: #{$alert-border-radius}; 15 | --#{$prefix}alert-link-color: inherit; 16 | // scss-docs-end alert-css-vars 17 | 18 | position: relative; 19 | padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x); 20 | margin-bottom: var(--#{$prefix}alert-margin-bottom); 21 | color: var(--#{$prefix}alert-color); 22 | background-color: var(--#{$prefix}alert-bg); 23 | border: var(--#{$prefix}alert-border); 24 | @include border-radius(var(--#{$prefix}alert-border-radius)); 25 | } 26 | 27 | // Headings for larger alerts 28 | .alert-heading { 29 | // Specified to prevent conflicts of changing $headings-color 30 | color: inherit; 31 | } 32 | 33 | // Provide class for links that match alerts 34 | .alert-link { 35 | font-weight: $alert-link-font-weight; 36 | color: var(--#{$prefix}alert-link-color); 37 | } 38 | 39 | 40 | // Dismissible alerts 41 | // 42 | // Expand the right padding and account for the close button's positioning. 43 | 44 | .alert-dismissible { 45 | padding-right: $alert-dismissible-padding-r; 46 | 47 | // Adjust close link position 48 | .btn-close { 49 | position: absolute; 50 | top: 0; 51 | right: 0; 52 | z-index: $stretched-link-z-index + 1; 53 | padding: $alert-padding-y * 1.25 $alert-padding-x; 54 | } 55 | } 56 | 57 | 58 | // scss-docs-start alert-modifiers 59 | // Generate contextual modifier classes for colorizing the alert 60 | @each $state in map-keys($theme-colors) { 61 | .alert-#{$state} { 62 | --#{$prefix}alert-color: var(--#{$prefix}#{$state}-text-emphasis); 63 | --#{$prefix}alert-bg: var(--#{$prefix}#{$state}-bg-subtle); 64 | --#{$prefix}alert-border-color: var(--#{$prefix}#{$state}-border-subtle); 65 | --#{$prefix}alert-link-color: var(--#{$prefix}#{$state}-text-emphasis); 66 | } 67 | } 68 | // scss-docs-end alert-modifiers 69 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_badge.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Requires one of the contextual, color modifier classes for `color` and 4 | // `background-color`. 5 | 6 | .badge { 7 | // scss-docs-start badge-css-vars 8 | --#{$prefix}badge-padding-x: #{$badge-padding-x}; 9 | --#{$prefix}badge-padding-y: #{$badge-padding-y}; 10 | @include rfs($badge-font-size, --#{$prefix}badge-font-size); 11 | --#{$prefix}badge-font-weight: #{$badge-font-weight}; 12 | --#{$prefix}badge-color: #{$badge-color}; 13 | --#{$prefix}badge-border-radius: #{$badge-border-radius}; 14 | // scss-docs-end badge-css-vars 15 | 16 | display: inline-block; 17 | padding: var(--#{$prefix}badge-padding-y) var(--#{$prefix}badge-padding-x); 18 | @include font-size(var(--#{$prefix}badge-font-size)); 19 | font-weight: var(--#{$prefix}badge-font-weight); 20 | line-height: 1; 21 | color: var(--#{$prefix}badge-color); 22 | text-align: center; 23 | white-space: nowrap; 24 | vertical-align: baseline; 25 | @include border-radius(var(--#{$prefix}badge-border-radius)); 26 | @include gradient-bg(); 27 | 28 | // Empty badges collapse automatically 29 | &:empty { 30 | display: none; 31 | } 32 | } 33 | 34 | // Quick fix for badges in buttons 35 | .btn .badge { 36 | position: relative; 37 | top: -1px; 38 | } 39 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | // scss-docs-start breadcrumb-css-vars 3 | --#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x}; 4 | --#{$prefix}breadcrumb-padding-y: #{$breadcrumb-padding-y}; 5 | --#{$prefix}breadcrumb-margin-bottom: #{$breadcrumb-margin-bottom}; 6 | @include rfs($breadcrumb-font-size, --#{$prefix}breadcrumb-font-size); 7 | --#{$prefix}breadcrumb-bg: #{$breadcrumb-bg}; 8 | --#{$prefix}breadcrumb-border-radius: #{$breadcrumb-border-radius}; 9 | --#{$prefix}breadcrumb-divider-color: #{$breadcrumb-divider-color}; 10 | --#{$prefix}breadcrumb-item-padding-x: #{$breadcrumb-item-padding-x}; 11 | --#{$prefix}breadcrumb-item-active-color: #{$breadcrumb-active-color}; 12 | // scss-docs-end breadcrumb-css-vars 13 | 14 | display: flex; 15 | flex-wrap: wrap; 16 | padding: var(--#{$prefix}breadcrumb-padding-y) var(--#{$prefix}breadcrumb-padding-x); 17 | margin-bottom: var(--#{$prefix}breadcrumb-margin-bottom); 18 | @include font-size(var(--#{$prefix}breadcrumb-font-size)); 19 | list-style: none; 20 | background-color: var(--#{$prefix}breadcrumb-bg); 21 | @include border-radius(var(--#{$prefix}breadcrumb-border-radius)); 22 | } 23 | 24 | .breadcrumb-item { 25 | // The separator between breadcrumbs (by default, a forward-slash: "/") 26 | + .breadcrumb-item { 27 | padding-left: var(--#{$prefix}breadcrumb-item-padding-x); 28 | 29 | &::before { 30 | float: left; // Suppress inline spacings and underlining of the separator 31 | padding-right: var(--#{$prefix}breadcrumb-item-padding-x); 32 | color: var(--#{$prefix}breadcrumb-divider-color); 33 | content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"}; 34 | } 35 | } 36 | 37 | &.active { 38 | color: var(--#{$prefix}breadcrumb-item-active-color); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_button-group.scss: -------------------------------------------------------------------------------- 1 | // Make the div behave like a button 2 | .btn-group, 3 | .btn-group-vertical { 4 | position: relative; 5 | display: inline-flex; 6 | vertical-align: middle; // match .btn alignment given font-size hack above 7 | 8 | > .btn { 9 | position: relative; 10 | flex: 1 1 auto; 11 | } 12 | 13 | // Bring the hover, focused, and "active" buttons to the front to overlay 14 | // the borders properly 15 | > .btn-check:checked + .btn, 16 | > .btn-check:focus + .btn, 17 | > .btn:hover, 18 | > .btn:focus, 19 | > .btn:active, 20 | > .btn.active { 21 | z-index: 1; 22 | } 23 | } 24 | 25 | // Optional: Group multiple button groups together for a toolbar 26 | .btn-toolbar { 27 | display: flex; 28 | flex-wrap: wrap; 29 | justify-content: flex-start; 30 | 31 | .input-group { 32 | width: auto; 33 | } 34 | } 35 | 36 | .btn-group { 37 | @include border-radius($btn-border-radius); 38 | 39 | // Prevent double borders when buttons are next to each other 40 | > :not(.btn-check:first-child) + .btn, 41 | > .btn-group:not(:first-child) { 42 | margin-left: calc(-1 * #{$btn-border-width}); // stylelint-disable-line function-disallowed-list 43 | } 44 | 45 | // Reset rounded corners 46 | > .btn:not(:last-child):not(.dropdown-toggle), 47 | > .btn.dropdown-toggle-split:first-child, 48 | > .btn-group:not(:last-child) > .btn { 49 | @include border-end-radius(0); 50 | } 51 | 52 | // The left radius should be 0 if the button is: 53 | // - the "third or more" child 54 | // - the second child and the previous element isn't `.btn-check` (making it the first child visually) 55 | // - part of a btn-group which isn't the first child 56 | > .btn:nth-child(n + 3), 57 | > :not(.btn-check) + .btn, 58 | > .btn-group:not(:first-child) > .btn { 59 | @include border-start-radius(0); 60 | } 61 | } 62 | 63 | // Sizing 64 | // 65 | // Remix the default button sizing classes into new ones for easier manipulation. 66 | 67 | .btn-group-sm > .btn { @extend .btn-sm; } 68 | .btn-group-lg > .btn { @extend .btn-lg; } 69 | 70 | 71 | // 72 | // Split button dropdowns 73 | // 74 | 75 | .dropdown-toggle-split { 76 | padding-right: $btn-padding-x * .75; 77 | padding-left: $btn-padding-x * .75; 78 | 79 | &::after, 80 | .dropup &::after, 81 | .dropend &::after { 82 | margin-left: 0; 83 | } 84 | 85 | .dropstart &::before { 86 | margin-right: 0; 87 | } 88 | } 89 | 90 | .btn-sm + .dropdown-toggle-split { 91 | padding-right: $btn-padding-x-sm * .75; 92 | padding-left: $btn-padding-x-sm * .75; 93 | } 94 | 95 | .btn-lg + .dropdown-toggle-split { 96 | padding-right: $btn-padding-x-lg * .75; 97 | padding-left: $btn-padding-x-lg * .75; 98 | } 99 | 100 | 101 | // The clickable button for toggling the menu 102 | // Set the same inset shadow as the :active state 103 | .btn-group.show .dropdown-toggle { 104 | @include box-shadow($btn-active-box-shadow); 105 | 106 | // Show no shadow for `.btn-link` since it has no other button styles. 107 | &.btn-link { 108 | @include box-shadow(none); 109 | } 110 | } 111 | 112 | 113 | // 114 | // Vertical button groups 115 | // 116 | 117 | .btn-group-vertical { 118 | flex-direction: column; 119 | align-items: flex-start; 120 | justify-content: center; 121 | 122 | > .btn, 123 | > .btn-group { 124 | width: 100%; 125 | } 126 | 127 | > .btn:not(:first-child), 128 | > .btn-group:not(:first-child) { 129 | margin-top: calc(-1 * #{$btn-border-width}); // stylelint-disable-line function-disallowed-list 130 | } 131 | 132 | // Reset rounded corners 133 | > .btn:not(:last-child):not(.dropdown-toggle), 134 | > .btn-group:not(:last-child) > .btn { 135 | @include border-bottom-radius(0); 136 | } 137 | 138 | // The top radius should be 0 if the button is: 139 | // - the "third or more" child 140 | // - the second child and the previous element isn't `.btn-check` (making it the first child visually) 141 | // - part of a btn-group which isn't the first child 142 | > .btn:nth-child(n + 3), 143 | > :not(.btn-check) + .btn, 144 | > .btn-group:not(:first-child) > .btn { 145 | @include border-top-radius(0); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_carousel.scss: -------------------------------------------------------------------------------- 1 | // Notes on the classes: 2 | // 3 | // 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically) 4 | // even when their scroll action started on a carousel, but for compatibility (with Firefox) 5 | // we're preventing all actions instead 6 | // 2. The .carousel-item-start and .carousel-item-end is used to indicate where 7 | // the active slide is heading. 8 | // 3. .active.carousel-item is the current slide. 9 | // 4. .active.carousel-item-start and .active.carousel-item-end is the current 10 | // slide in its in-transition state. Only one of these occurs at a time. 11 | // 5. .carousel-item-next.carousel-item-start and .carousel-item-prev.carousel-item-end 12 | // is the upcoming slide in transition. 13 | 14 | .carousel { 15 | position: relative; 16 | } 17 | 18 | .carousel.pointer-event { 19 | touch-action: pan-y; 20 | } 21 | 22 | .carousel-inner { 23 | position: relative; 24 | width: 100%; 25 | overflow: hidden; 26 | @include clearfix(); 27 | } 28 | 29 | .carousel-item { 30 | position: relative; 31 | display: none; 32 | float: left; 33 | width: 100%; 34 | margin-right: -100%; 35 | backface-visibility: hidden; 36 | @include transition($carousel-transition); 37 | } 38 | 39 | .carousel-item.active, 40 | .carousel-item-next, 41 | .carousel-item-prev { 42 | display: block; 43 | } 44 | 45 | .carousel-item-next:not(.carousel-item-start), 46 | .active.carousel-item-end { 47 | transform: translateX(100%); 48 | } 49 | 50 | .carousel-item-prev:not(.carousel-item-end), 51 | .active.carousel-item-start { 52 | transform: translateX(-100%); 53 | } 54 | 55 | 56 | // 57 | // Alternate transitions 58 | // 59 | 60 | .carousel-fade { 61 | .carousel-item { 62 | opacity: 0; 63 | transition-property: opacity; 64 | transform: none; 65 | } 66 | 67 | .carousel-item.active, 68 | .carousel-item-next.carousel-item-start, 69 | .carousel-item-prev.carousel-item-end { 70 | z-index: 1; 71 | opacity: 1; 72 | } 73 | 74 | .active.carousel-item-start, 75 | .active.carousel-item-end { 76 | z-index: 0; 77 | opacity: 0; 78 | @include transition(opacity 0s $carousel-transition-duration); 79 | } 80 | } 81 | 82 | 83 | // 84 | // Left/right controls for nav 85 | // 86 | 87 | .carousel-control-prev, 88 | .carousel-control-next { 89 | position: absolute; 90 | top: 0; 91 | bottom: 0; 92 | z-index: 1; 93 | // Use flex for alignment (1-3) 94 | display: flex; // 1. allow flex styles 95 | align-items: center; // 2. vertically center contents 96 | justify-content: center; // 3. horizontally center contents 97 | width: $carousel-control-width; 98 | padding: 0; 99 | color: $carousel-control-color; 100 | text-align: center; 101 | background: none; 102 | filter: var(--#{$prefix}carousel-control-icon-filter); 103 | border: 0; 104 | opacity: $carousel-control-opacity; 105 | @include transition($carousel-control-transition); 106 | 107 | // Hover/focus state 108 | &:hover, 109 | &:focus { 110 | color: $carousel-control-color; 111 | text-decoration: none; 112 | outline: 0; 113 | opacity: $carousel-control-hover-opacity; 114 | } 115 | } 116 | .carousel-control-prev { 117 | left: 0; 118 | background-image: if($enable-gradients, linear-gradient(90deg, rgba($black, .25), rgba($black, .001)), null); 119 | } 120 | .carousel-control-next { 121 | right: 0; 122 | background-image: if($enable-gradients, linear-gradient(270deg, rgba($black, .25), rgba($black, .001)), null); 123 | } 124 | 125 | // Icons for within 126 | .carousel-control-prev-icon, 127 | .carousel-control-next-icon { 128 | display: inline-block; 129 | width: $carousel-control-icon-width; 130 | height: $carousel-control-icon-width; 131 | background-repeat: no-repeat; 132 | background-position: 50%; 133 | background-size: 100% 100%; 134 | } 135 | 136 | .carousel-control-prev-icon { 137 | background-image: escape-svg($carousel-control-prev-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-next-icon-bg) + "*/"}; 138 | } 139 | .carousel-control-next-icon { 140 | background-image: escape-svg($carousel-control-next-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-prev-icon-bg) + "*/"}; 141 | } 142 | 143 | // Optional indicator pips/controls 144 | // 145 | // Add a container (such as a list) with the following class and add an item (ideally a focusable control, 146 | // like a button) with data-bs-target for each slide your carousel holds. 147 | 148 | .carousel-indicators { 149 | position: absolute; 150 | right: 0; 151 | bottom: 0; 152 | left: 0; 153 | z-index: 2; 154 | display: flex; 155 | justify-content: center; 156 | padding: 0; 157 | // Use the .carousel-control's width as margin so we don't overlay those 158 | margin-right: $carousel-control-width; 159 | margin-bottom: 1rem; 160 | margin-left: $carousel-control-width; 161 | 162 | [data-bs-target] { 163 | box-sizing: content-box; 164 | flex: 0 1 auto; 165 | width: $carousel-indicator-width; 166 | height: $carousel-indicator-height; 167 | padding: 0; 168 | margin-right: $carousel-indicator-spacer; 169 | margin-left: $carousel-indicator-spacer; 170 | text-indent: -999px; 171 | cursor: pointer; 172 | background-color: var(--#{$prefix}carousel-indicator-active-bg); 173 | background-clip: padding-box; 174 | border: 0; 175 | // Use transparent borders to increase the hit area by 10px on top and bottom. 176 | border-top: $carousel-indicator-hit-area-height solid transparent; 177 | border-bottom: $carousel-indicator-hit-area-height solid transparent; 178 | opacity: $carousel-indicator-opacity; 179 | @include transition($carousel-indicator-transition); 180 | } 181 | 182 | .active { 183 | opacity: $carousel-indicator-active-opacity; 184 | } 185 | } 186 | 187 | 188 | // Optional captions 189 | // 190 | // 191 | 192 | .carousel-caption { 193 | position: absolute; 194 | right: (100% - $carousel-caption-width) * .5; 195 | bottom: $carousel-caption-spacer; 196 | left: (100% - $carousel-caption-width) * .5; 197 | padding-top: $carousel-caption-padding-y; 198 | padding-bottom: $carousel-caption-padding-y; 199 | color: var(--#{$prefix}carousel-caption-color); 200 | text-align: center; 201 | } 202 | 203 | // Dark mode carousel 204 | 205 | @mixin carousel-dark() { 206 | --#{$prefix}carousel-indicator-active-bg: #{$carousel-indicator-active-bg-dark}; 207 | --#{$prefix}carousel-caption-color: #{$carousel-caption-color-dark}; 208 | --#{$prefix}carousel-control-icon-filter: #{$carousel-control-icon-filter-dark}; 209 | } 210 | 211 | .carousel-dark { 212 | @include carousel-dark(); 213 | } 214 | 215 | :root, 216 | [data-bs-theme="light"] { 217 | --#{$prefix}carousel-indicator-active-bg: #{$carousel-indicator-active-bg}; 218 | --#{$prefix}carousel-caption-color: #{$carousel-caption-color}; 219 | --#{$prefix}carousel-control-icon-filter: #{$carousel-control-icon-filter}; 220 | } 221 | 222 | @if $enable-dark-mode { 223 | @include color-mode(dark, true) { 224 | @include carousel-dark(); 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_close.scss: -------------------------------------------------------------------------------- 1 | // Transparent background and border properties included for button version. 2 | // iOS requires the button element instead of an anchor tag. 3 | // If you want the anchor version, it requires `href="#"`. 4 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 5 | 6 | .btn-close { 7 | // scss-docs-start close-css-vars 8 | --#{$prefix}btn-close-color: #{$btn-close-color}; 9 | --#{$prefix}btn-close-bg: #{ escape-svg($btn-close-bg) }; 10 | --#{$prefix}btn-close-opacity: #{$btn-close-opacity}; 11 | --#{$prefix}btn-close-hover-opacity: #{$btn-close-hover-opacity}; 12 | --#{$prefix}btn-close-focus-shadow: #{$btn-close-focus-shadow}; 13 | --#{$prefix}btn-close-focus-opacity: #{$btn-close-focus-opacity}; 14 | --#{$prefix}btn-close-disabled-opacity: #{$btn-close-disabled-opacity}; 15 | // scss-docs-end close-css-vars 16 | 17 | box-sizing: content-box; 18 | width: $btn-close-width; 19 | height: $btn-close-height; 20 | padding: $btn-close-padding-y $btn-close-padding-x; 21 | color: var(--#{$prefix}btn-close-color); 22 | background: transparent var(--#{$prefix}btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements 23 | filter: var(--#{$prefix}btn-close-filter); 24 | border: 0; // for button elements 25 | @include border-radius(); 26 | opacity: var(--#{$prefix}btn-close-opacity); 27 | 28 | // Override 's hover style 29 | &:hover { 30 | color: var(--#{$prefix}btn-close-color); 31 | text-decoration: none; 32 | opacity: var(--#{$prefix}btn-close-hover-opacity); 33 | } 34 | 35 | &:focus { 36 | outline: 0; 37 | box-shadow: var(--#{$prefix}btn-close-focus-shadow); 38 | opacity: var(--#{$prefix}btn-close-focus-opacity); 39 | } 40 | 41 | &:disabled, 42 | &.disabled { 43 | pointer-events: none; 44 | user-select: none; 45 | opacity: var(--#{$prefix}btn-close-disabled-opacity); 46 | } 47 | } 48 | 49 | @mixin btn-close-white() { 50 | --#{$prefix}btn-close-filter: #{$btn-close-filter-dark}; 51 | } 52 | 53 | .btn-close-white { 54 | @include btn-close-white(); 55 | } 56 | 57 | :root, 58 | [data-bs-theme="light"] { 59 | --#{$prefix}btn-close-filter: #{$btn-close-filter}; 60 | } 61 | 62 | @if $enable-dark-mode { 63 | @include color-mode(dark, true) { 64 | @include btn-close-white(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_containers.scss: -------------------------------------------------------------------------------- 1 | // Container widths 2 | // 3 | // Set the container width, and override it for fixed navbars in media queries. 4 | 5 | @if $enable-container-classes { 6 | // Single container class with breakpoint max-widths 7 | .container, 8 | // 100% wide container at all breakpoints 9 | .container-fluid { 10 | @include make-container(); 11 | } 12 | 13 | // Responsive containers that are 100% wide until a breakpoint 14 | @each $breakpoint, $container-max-width in $container-max-widths { 15 | .container-#{$breakpoint} { 16 | @extend .container-fluid; 17 | } 18 | 19 | @include media-breakpoint-up($breakpoint, $grid-breakpoints) { 20 | %responsive-container-#{$breakpoint} { 21 | max-width: $container-max-width; 22 | } 23 | 24 | // Extend each breakpoint which is smaller or equal to the current breakpoint 25 | $extend-breakpoint: true; 26 | 27 | @each $name, $width in $grid-breakpoints { 28 | @if ($extend-breakpoint) { 29 | .container#{breakpoint-infix($name, $grid-breakpoints)} { 30 | @extend %responsive-container-#{$breakpoint}; 31 | } 32 | 33 | // Once the current breakpoint is reached, stop extending 34 | @if ($breakpoint == $name) { 35 | $extend-breakpoint: false; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_forms.scss: -------------------------------------------------------------------------------- 1 | @import "forms/labels"; 2 | @import "forms/form-text"; 3 | @import "forms/form-control"; 4 | @import "forms/form-select"; 5 | @import "forms/form-check"; 6 | @import "forms/form-range"; 7 | @import "forms/floating-labels"; 8 | @import "forms/input-group"; 9 | @import "forms/validation"; 10 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_grid.scss: -------------------------------------------------------------------------------- 1 | // Row 2 | // 3 | // Rows contain your columns. 4 | 5 | :root { 6 | @each $name, $value in $grid-breakpoints { 7 | --#{$prefix}breakpoint-#{$name}: #{$value}; 8 | } 9 | } 10 | 11 | @if $enable-grid-classes { 12 | .row { 13 | @include make-row(); 14 | 15 | > * { 16 | @include make-col-ready(); 17 | } 18 | } 19 | } 20 | 21 | @if $enable-cssgrid { 22 | .grid { 23 | display: grid; 24 | grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr); 25 | grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr); 26 | gap: var(--#{$prefix}gap, #{$grid-gutter-width}); 27 | 28 | @include make-cssgrid(); 29 | } 30 | } 31 | 32 | 33 | // Columns 34 | // 35 | // Common styles for small and large grid columns 36 | 37 | @if $enable-grid-classes { 38 | @include make-grid-columns(); 39 | } 40 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_helpers.scss: -------------------------------------------------------------------------------- 1 | @import "helpers/clearfix"; 2 | @import "helpers/color-bg"; 3 | @import "helpers/colored-links"; 4 | @import "helpers/focus-ring"; 5 | @import "helpers/icon-link"; 6 | @import "helpers/ratio"; 7 | @import "helpers/position"; 8 | @import "helpers/stacks"; 9 | @import "helpers/visually-hidden"; 10 | @import "helpers/stretched-link"; 11 | @import "helpers/text-truncation"; 12 | @import "helpers/vr"; 13 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_images.scss: -------------------------------------------------------------------------------- 1 | // Responsive images (ensure images don't scale beyond their parents) 2 | // 3 | // This is purposefully opt-in via an explicit class rather than being the default for all ``s. 4 | // We previously tried the "images are responsive by default" approach in Bootstrap v2, 5 | // and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps) 6 | // which weren't expecting the images within themselves to be involuntarily resized. 7 | // See also https://github.com/twbs/bootstrap/issues/18178 8 | .img-fluid { 9 | @include img-fluid(); 10 | } 11 | 12 | 13 | // Image thumbnails 14 | .img-thumbnail { 15 | padding: $thumbnail-padding; 16 | background-color: $thumbnail-bg; 17 | border: $thumbnail-border-width solid $thumbnail-border-color; 18 | @include border-radius($thumbnail-border-radius); 19 | @include box-shadow($thumbnail-box-shadow); 20 | 21 | // Keep them at most 100% wide 22 | @include img-fluid(); 23 | } 24 | 25 | // 26 | // Figures 27 | // 28 | 29 | .figure { 30 | // Ensures the caption's text aligns with the image. 31 | display: inline-block; 32 | } 33 | 34 | .figure-img { 35 | margin-bottom: $spacer * .5; 36 | line-height: 1; 37 | } 38 | 39 | .figure-caption { 40 | @include font-size($figure-caption-font-size); 41 | color: $figure-caption-color; 42 | } 43 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_maps.scss: -------------------------------------------------------------------------------- 1 | // Re-assigned maps 2 | // 3 | // Placed here so that others can override the default Sass maps and see automatic updates to utilities and more. 4 | 5 | // scss-docs-start theme-colors-rgb 6 | $theme-colors-rgb: map-loop($theme-colors, to-rgb, "$value") !default; 7 | // scss-docs-end theme-colors-rgb 8 | 9 | // scss-docs-start theme-text-map 10 | $theme-colors-text: ( 11 | "primary": $primary-text-emphasis, 12 | "secondary": $secondary-text-emphasis, 13 | "success": $success-text-emphasis, 14 | "info": $info-text-emphasis, 15 | "warning": $warning-text-emphasis, 16 | "danger": $danger-text-emphasis, 17 | "light": $light-text-emphasis, 18 | "dark": $dark-text-emphasis, 19 | ) !default; 20 | // scss-docs-end theme-text-map 21 | 22 | // scss-docs-start theme-bg-subtle-map 23 | $theme-colors-bg-subtle: ( 24 | "primary": $primary-bg-subtle, 25 | "secondary": $secondary-bg-subtle, 26 | "success": $success-bg-subtle, 27 | "info": $info-bg-subtle, 28 | "warning": $warning-bg-subtle, 29 | "danger": $danger-bg-subtle, 30 | "light": $light-bg-subtle, 31 | "dark": $dark-bg-subtle, 32 | ) !default; 33 | // scss-docs-end theme-bg-subtle-map 34 | 35 | // scss-docs-start theme-border-subtle-map 36 | $theme-colors-border-subtle: ( 37 | "primary": $primary-border-subtle, 38 | "secondary": $secondary-border-subtle, 39 | "success": $success-border-subtle, 40 | "info": $info-border-subtle, 41 | "warning": $warning-border-subtle, 42 | "danger": $danger-border-subtle, 43 | "light": $light-border-subtle, 44 | "dark": $dark-border-subtle, 45 | ) !default; 46 | // scss-docs-end theme-border-subtle-map 47 | 48 | $theme-colors-text-dark: null !default; 49 | $theme-colors-bg-subtle-dark: null !default; 50 | $theme-colors-border-subtle-dark: null !default; 51 | 52 | @if $enable-dark-mode { 53 | // scss-docs-start theme-text-dark-map 54 | $theme-colors-text-dark: ( 55 | "primary": $primary-text-emphasis-dark, 56 | "secondary": $secondary-text-emphasis-dark, 57 | "success": $success-text-emphasis-dark, 58 | "info": $info-text-emphasis-dark, 59 | "warning": $warning-text-emphasis-dark, 60 | "danger": $danger-text-emphasis-dark, 61 | "light": $light-text-emphasis-dark, 62 | "dark": $dark-text-emphasis-dark, 63 | ) !default; 64 | // scss-docs-end theme-text-dark-map 65 | 66 | // scss-docs-start theme-bg-subtle-dark-map 67 | $theme-colors-bg-subtle-dark: ( 68 | "primary": $primary-bg-subtle-dark, 69 | "secondary": $secondary-bg-subtle-dark, 70 | "success": $success-bg-subtle-dark, 71 | "info": $info-bg-subtle-dark, 72 | "warning": $warning-bg-subtle-dark, 73 | "danger": $danger-bg-subtle-dark, 74 | "light": $light-bg-subtle-dark, 75 | "dark": $dark-bg-subtle-dark, 76 | ) !default; 77 | // scss-docs-end theme-bg-subtle-dark-map 78 | 79 | // scss-docs-start theme-border-subtle-dark-map 80 | $theme-colors-border-subtle-dark: ( 81 | "primary": $primary-border-subtle-dark, 82 | "secondary": $secondary-border-subtle-dark, 83 | "success": $success-border-subtle-dark, 84 | "info": $info-border-subtle-dark, 85 | "warning": $warning-border-subtle-dark, 86 | "danger": $danger-border-subtle-dark, 87 | "light": $light-border-subtle-dark, 88 | "dark": $dark-border-subtle-dark, 89 | ) !default; 90 | // scss-docs-end theme-border-subtle-dark-map 91 | } 92 | 93 | // Utilities maps 94 | // 95 | // Extends the default `$theme-colors` maps to help create our utilities. 96 | 97 | // Come v6, we'll de-dupe these variables. Until then, for backward compatibility, we keep them to reassign. 98 | // scss-docs-start utilities-colors 99 | $utilities-colors: $theme-colors-rgb !default; 100 | // scss-docs-end utilities-colors 101 | 102 | // scss-docs-start utilities-text-colors 103 | $utilities-text: map-merge( 104 | $utilities-colors, 105 | ( 106 | "black": to-rgb($black), 107 | "white": to-rgb($white), 108 | "body": to-rgb($body-color) 109 | ) 110 | ) !default; 111 | $utilities-text-colors: map-loop($utilities-text, rgba-css-var, "$key", "text") !default; 112 | 113 | $utilities-text-emphasis-colors: ( 114 | "primary-emphasis": var(--#{$prefix}primary-text-emphasis), 115 | "secondary-emphasis": var(--#{$prefix}secondary-text-emphasis), 116 | "success-emphasis": var(--#{$prefix}success-text-emphasis), 117 | "info-emphasis": var(--#{$prefix}info-text-emphasis), 118 | "warning-emphasis": var(--#{$prefix}warning-text-emphasis), 119 | "danger-emphasis": var(--#{$prefix}danger-text-emphasis), 120 | "light-emphasis": var(--#{$prefix}light-text-emphasis), 121 | "dark-emphasis": var(--#{$prefix}dark-text-emphasis) 122 | ) !default; 123 | // scss-docs-end utilities-text-colors 124 | 125 | // scss-docs-start utilities-bg-colors 126 | $utilities-bg: map-merge( 127 | $utilities-colors, 128 | ( 129 | "black": to-rgb($black), 130 | "white": to-rgb($white), 131 | "body": to-rgb($body-bg) 132 | ) 133 | ) !default; 134 | $utilities-bg-colors: map-loop($utilities-bg, rgba-css-var, "$key", "bg") !default; 135 | 136 | $utilities-bg-subtle: ( 137 | "primary-subtle": var(--#{$prefix}primary-bg-subtle), 138 | "secondary-subtle": var(--#{$prefix}secondary-bg-subtle), 139 | "success-subtle": var(--#{$prefix}success-bg-subtle), 140 | "info-subtle": var(--#{$prefix}info-bg-subtle), 141 | "warning-subtle": var(--#{$prefix}warning-bg-subtle), 142 | "danger-subtle": var(--#{$prefix}danger-bg-subtle), 143 | "light-subtle": var(--#{$prefix}light-bg-subtle), 144 | "dark-subtle": var(--#{$prefix}dark-bg-subtle) 145 | ) !default; 146 | // scss-docs-end utilities-bg-colors 147 | 148 | // scss-docs-start utilities-border-colors 149 | $utilities-border: map-merge( 150 | $utilities-colors, 151 | ( 152 | "black": to-rgb($black), 153 | "white": to-rgb($white) 154 | ) 155 | ) !default; 156 | $utilities-border-colors: map-loop($utilities-border, rgba-css-var, "$key", "border") !default; 157 | 158 | $utilities-border-subtle: ( 159 | "primary-subtle": var(--#{$prefix}primary-border-subtle), 160 | "secondary-subtle": var(--#{$prefix}secondary-border-subtle), 161 | "success-subtle": var(--#{$prefix}success-border-subtle), 162 | "info-subtle": var(--#{$prefix}info-border-subtle), 163 | "warning-subtle": var(--#{$prefix}warning-border-subtle), 164 | "danger-subtle": var(--#{$prefix}danger-border-subtle), 165 | "light-subtle": var(--#{$prefix}light-border-subtle), 166 | "dark-subtle": var(--#{$prefix}dark-border-subtle) 167 | ) !default; 168 | // scss-docs-end utilities-border-colors 169 | 170 | $utilities-links-underline: map-loop($utilities-colors, rgba-css-var, "$key", "link-underline") !default; 171 | 172 | $negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default; 173 | 174 | $gutters: $spacers !default; 175 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Toggles 2 | // 3 | // Used in conjunction with global variables to enable certain theme features. 4 | 5 | // Vendor 6 | @import "vendor/rfs"; 7 | 8 | // Deprecate 9 | @import "mixins/deprecate"; 10 | 11 | // Helpers 12 | @import "mixins/breakpoints"; 13 | @import "mixins/color-mode"; 14 | @import "mixins/color-scheme"; 15 | @import "mixins/image"; 16 | @import "mixins/resize"; 17 | @import "mixins/visually-hidden"; 18 | @import "mixins/reset-text"; 19 | @import "mixins/text-truncate"; 20 | 21 | // Utilities 22 | @import "mixins/utilities"; 23 | 24 | // Components 25 | @import "mixins/backdrop"; 26 | @import "mixins/buttons"; 27 | @import "mixins/caret"; 28 | @import "mixins/pagination"; 29 | @import "mixins/lists"; 30 | @import "mixins/forms"; 31 | @import "mixins/table-variants"; 32 | 33 | // Skins 34 | @import "mixins/border-radius"; 35 | @import "mixins/box-shadow"; 36 | @import "mixins/gradients"; 37 | @import "mixins/transition"; 38 | 39 | // Layout 40 | @import "mixins/clearfix"; 41 | @import "mixins/container"; 42 | @import "mixins/grid"; 43 | -------------------------------------------------------------------------------- /_sass/bootstrap/scss/_nav.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Kickstart any navigation component with a set of style resets. Works with 4 | // `