aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/templates/assets/stylesheets/main
diff options
context:
space:
mode:
author简律纯 <i@jyunko.cn>2023-10-07 06:48:07 +0800
committer简律纯 <i@jyunko.cn>2023-10-07 06:48:07 +0800
commit991fd7a6d67ee017c57beaaa21fc31c4bee7944d (patch)
treee895202203fcaa50b0052f60ef6fc7d6d2928cf9 /src/templates/assets/stylesheets/main
parentd62900046bb6f754a8e6e7e670a66a90134055d9 (diff)
downloadinfini-991fd7a6d67ee017c57beaaa21fc31c4bee7944d.tar.gz
infini-991fd7a6d67ee017c57beaaa21fc31c4bee7944d.zip
feat(version): versions
Diffstat (limited to 'src/templates/assets/stylesheets/main')
-rw-r--r--src/templates/assets/stylesheets/main/_colors.scss153
-rw-r--r--src/templates/assets/stylesheets/main/_icons.scss37
-rw-r--r--src/templates/assets/stylesheets/main/_modifiers.scss48
-rw-r--r--src/templates/assets/stylesheets/main/_resets.scss118
-rw-r--r--src/templates/assets/stylesheets/main/_typeset.scss603
-rw-r--r--src/templates/assets/stylesheets/main/components/_author.scss86
-rw-r--r--src/templates/assets/stylesheets/main/components/_banner.scss68
-rw-r--r--src/templates/assets/stylesheets/main/components/_base.scss182
-rw-r--r--src/templates/assets/stylesheets/main/components/_clipboard.scss102
-rw-r--r--src/templates/assets/stylesheets/main/components/_consent.scss127
-rw-r--r--src/templates/assets/stylesheets/main/components/_content.scss97
-rw-r--r--src/templates/assets/stylesheets/main/components/_dialog.scss65
-rw-r--r--src/templates/assets/stylesheets/main/components/_feedback.scss110
-rw-r--r--src/templates/assets/stylesheets/main/components/_footer.scss201
-rw-r--r--src/templates/assets/stylesheets/main/components/_form.scss83
-rw-r--r--src/templates/assets/stylesheets/main/components/_header.scss270
-rw-r--r--src/templates/assets/stylesheets/main/components/_meta.scss67
-rw-r--r--src/templates/assets/stylesheets/main/components/_nav.scss761
-rw-r--r--src/templates/assets/stylesheets/main/components/_pagination.scss85
-rw-r--r--src/templates/assets/stylesheets/main/components/_post.scss196
-rw-r--r--src/templates/assets/stylesheets/main/components/_progress.scss53
-rw-r--r--src/templates/assets/stylesheets/main/components/_search.scss707
-rw-r--r--src/templates/assets/stylesheets/main/components/_select.scss115
-rw-r--r--src/templates/assets/stylesheets/main/components/_sidebar.scss209
-rw-r--r--src/templates/assets/stylesheets/main/components/_source.scss182
-rw-r--r--src/templates/assets/stylesheets/main/components/_status.scss73
-rw-r--r--src/templates/assets/stylesheets/main/components/_tabs.scss133
-rw-r--r--src/templates/assets/stylesheets/main/components/_tag.scss105
-rw-r--r--src/templates/assets/stylesheets/main/components/_tooltip.scss292
-rw-r--r--src/templates/assets/stylesheets/main/components/_top.scss83
-rw-r--r--src/templates/assets/stylesheets/main/components/_version.scss150
-rw-r--r--src/templates/assets/stylesheets/main/extensions/markdown/_admonition.scss195
-rw-r--r--src/templates/assets/stylesheets/main/extensions/markdown/_footnotes.scss146
-rw-r--r--src/templates/assets/stylesheets/main/extensions/markdown/_toc.scss92
-rw-r--r--src/templates/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss52
-rw-r--r--src/templates/assets/stylesheets/main/extensions/pymdownx/_critic.scss76
-rw-r--r--src/templates/assets/stylesheets/main/extensions/pymdownx/_details.scss121
-rw-r--r--src/templates/assets/stylesheets/main/extensions/pymdownx/_emoji.scss43
-rw-r--r--src/templates/assets/stylesheets/main/extensions/pymdownx/_highlight.scss382
-rw-r--r--src/templates/assets/stylesheets/main/extensions/pymdownx/_keys.scss115
-rw-r--r--src/templates/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss400
-rw-r--r--src/templates/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss78
-rw-r--r--src/templates/assets/stylesheets/main/integrations/_mermaid.scss67
43 files changed, 7328 insertions, 0 deletions
diff --git a/src/templates/assets/stylesheets/main/_colors.scss b/src/templates/assets/stylesheets/main/_colors.scss
new file mode 100644
index 00000000..68969fe9
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/_colors.scss
@@ -0,0 +1,153 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Color variables
+:root {
+ @extend %root;
+
+ // Primary color shades
+ --md-primary-fg-color: hsla(#{hex2hsl($clr-indigo-500)}, 1);
+ --md-primary-fg-color--light: hsla(#{hex2hsl($clr-indigo-400)}, 1);
+ --md-primary-fg-color--dark: hsla(#{hex2hsl($clr-indigo-700)}, 1);
+ --md-primary-bg-color: hsla(0, 0%, 100%, 1);
+ --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7);
+
+ // Accent color shades
+ --md-accent-fg-color: hsla(#{hex2hsl($clr-indigo-a200)}, 1);
+ --md-accent-fg-color--transparent: hsla(#{hex2hsl($clr-indigo-a200)}, 0.1);
+ --md-accent-bg-color: hsla(0, 0%, 100%, 1);
+ --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7);
+}
+
+// ----------------------------------------------------------------------------
+
+// Allow to explicitly use color schemes in nested content
+[data-md-color-scheme="default"] {
+ @extend %root;
+
+ // Indicate that the site is rendered with a light color scheme
+ color-scheme: light;
+
+ // Hide images for dark mode
+ img[src$="#only-dark"],
+ img[src$="#gh-dark-mode-only"] {
+ display: none;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Placeholders
+// ----------------------------------------------------------------------------
+
+// Default theme, i.e. light mode
+%root {
+
+ // Color hue in the range [0,360] - change this variable to alter the tone
+ // of the theme, e.g. to make it more redish or greenish
+ --md-hue: 225deg;
+
+ // Default color shades
+ --md-default-fg-color: hsla(0, 0%, 0%, 0.87);
+ --md-default-fg-color--light: hsla(0, 0%, 0%, 0.54);
+ --md-default-fg-color--lighter: hsla(0, 0%, 0%, 0.32);
+ --md-default-fg-color--lightest: hsla(0, 0%, 0%, 0.07);
+ --md-default-bg-color: hsla(0, 0%, 100%, 1);
+ --md-default-bg-color--light: hsla(0, 0%, 100%, 0.7);
+ --md-default-bg-color--lighter: hsla(0, 0%, 100%, 0.3);
+ --md-default-bg-color--lightest: hsla(0, 0%, 100%, 0.12);
+
+ // Code color shades
+ --md-code-fg-color: hsla(200, 18%, 26%, 1);
+ --md-code-bg-color: hsla(200, 0%, 96%, 1);
+
+ // Code highlighting color shades
+ --md-code-hl-color: hsla(#{hex2hsl($clr-blue-a200)}, 1);
+ --md-code-hl-color--light: hsla(#{hex2hsl($clr-blue-a200)}, 0.1);
+ --md-code-hl-number-color: hsla(0, 67%, 50%, 1);
+ --md-code-hl-special-color: hsla(340, 83%, 47%, 1);
+ --md-code-hl-function-color: hsla(291, 45%, 50%, 1);
+ --md-code-hl-constant-color: hsla(250, 63%, 60%, 1);
+ --md-code-hl-keyword-color: hsla(219, 54%, 51%, 1);
+ --md-code-hl-string-color: hsla(150, 63%, 30%, 1);
+ --md-code-hl-name-color: var(--md-code-fg-color);
+ --md-code-hl-operator-color: var(--md-default-fg-color--light);
+ --md-code-hl-punctuation-color: var(--md-default-fg-color--light);
+ --md-code-hl-comment-color: var(--md-default-fg-color--light);
+ --md-code-hl-generic-color: var(--md-default-fg-color--light);
+ --md-code-hl-variable-color: var(--md-default-fg-color--light);
+
+ // Typeset color shades
+ --md-typeset-color: var(--md-default-fg-color);
+
+ // Typeset `a` color shades
+ --md-typeset-a-color: var(--md-primary-fg-color);
+
+ // Typeset `del` and `ins` color shades
+ --md-typeset-del-color: hsla(6, 90%, 60%, 0.15);
+ --md-typeset-ins-color: hsla(150, 90%, 44%, 0.15);
+
+ // Typeset `kbd` color shades
+ --md-typeset-kbd-color: hsla(0, 0%, 98%, 1);
+ --md-typeset-kbd-accent-color: hsla(0, 100%, 100%, 1);
+ --md-typeset-kbd-border-color: hsla(0, 0%, 72%, 1);
+
+ // Typeset `mark` color shades
+ --md-typeset-mark-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5);
+
+ // Typeset `table` color shades
+ --md-typeset-table-color: hsla(0, 0%, 0%, 0.12);
+ --md-typeset-table-color--light: hsla(0, 0%, 0%, 0.035);
+
+ // Admonition color shades
+ --md-admonition-fg-color: var(--md-default-fg-color);
+ --md-admonition-bg-color: var(--md-default-bg-color);
+
+ // Warning color shades
+ --md-warning-fg-color: hsla(0, 0%, 0%, 0.87);
+ --md-warning-bg-color: hsla(60, 100%, 80%, 1);
+
+ // Footer color shades
+ --md-footer-fg-color: hsla(0, 0%, 100%, 1);
+ --md-footer-fg-color--light: hsla(0, 0%, 100%, 0.7);
+ --md-footer-fg-color--lighter: hsla(0, 0%, 100%, 0.45);
+ --md-footer-bg-color: hsla(0, 0%, 0%, 0.87);
+ --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.32);
+
+ // Shadow depth 1
+ --md-shadow-z1:
+ 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.05),
+ 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.1);
+
+ // Shadow depth 2
+ --md-shadow-z2:
+ 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.1),
+ 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.25);
+
+ // Shadow depth 3
+ --md-shadow-z3:
+ 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.2),
+ 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.35);
+}
diff --git a/src/templates/assets/stylesheets/main/_icons.scss b/src/templates/assets/stylesheets/main/_icons.scss
new file mode 100644
index 00000000..9853e93d
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/_icons.scss
@@ -0,0 +1,37 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Icon
+.md-icon {
+
+ // SVG defaults
+ svg {
+ display: block;
+ width: px2rem(24px);
+ height: px2rem(24px);
+ fill: currentcolor;
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/_modifiers.scss b/src/templates/assets/stylesheets/main/_modifiers.scss
new file mode 100644
index 00000000..4b2b046a
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/_modifiers.scss
@@ -0,0 +1,48 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // [tablet +]: Allow for rendering content as sidebars
+ @include break-from-device(tablet) {
+
+ // Modifier to float block elements
+ .inline {
+ float: inline-start;
+ width: px2rem(234px);
+ margin-inline-end: px2rem(16px);
+ margin-top: 0;
+ margin-bottom: px2rem(16px);
+
+ // Modifier to move to end (ltr: right, rtl: left)
+ &.end {
+ float: inline-end;
+ margin-inline: px2rem(16px) 0;
+ }
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/_resets.scss b/src/templates/assets/stylesheets/main/_resets.scss
new file mode 100644
index 00000000..c6fc4b28
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/_resets.scss
@@ -0,0 +1,118 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Enforce correct box model and prevent adjustments of font size after
+// orientation changes in IE and iOS
+html {
+ box-sizing: border-box;
+ text-size-adjust: none;
+}
+
+// All elements shall inherit the document default
+*,
+*::before,
+*::after {
+ box-sizing: inherit;
+
+ // [reduced motion]: Disable all transitions
+ @media (prefers-reduced-motion) {
+ transition: none !important; // stylelint-disable-line
+ }
+}
+
+// Remove margin in all browsers
+body {
+ margin: 0;
+}
+
+// Reset tap outlines on iOS and Android
+a,
+button,
+label,
+input {
+ -webkit-tap-highlight-color: transparent;
+}
+
+// Reset link styles
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+// Normalize horizontal separator styles
+hr {
+ box-sizing: content-box;
+ display: block;
+ height: px2rem(1px);
+ padding: 0;
+ overflow: visible;
+ border: 0;
+}
+
+// Normalize font-size in all browsers
+small {
+ font-size: 80%;
+}
+
+// Prevent subscript and superscript from affecting line-height
+sub,
+sup {
+ line-height: 1em;
+}
+
+// Remove border on image
+img {
+ border-style: none;
+}
+
+// Reset table styles
+table {
+ border-spacing: 0;
+ border-collapse: separate;
+}
+
+// Reset table cell styles
+td,
+th {
+ font-weight: 400;
+ vertical-align: top;
+}
+
+// Reset button styles
+button {
+ padding: 0;
+ margin: 0;
+ font-family: inherit;
+ font-size: inherit;
+ background: transparent;
+ border: 0;
+}
+
+// Reset input styles
+input {
+ border: 0;
+ outline: none;
+}
diff --git a/src/templates/assets/stylesheets/main/_typeset.scss b/src/templates/assets/stylesheets/main/_typeset.scss
new file mode 100644
index 00000000..1c322859
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/_typeset.scss
@@ -0,0 +1,603 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules: font definitions
+// ----------------------------------------------------------------------------
+
+// Enable font-smoothing in Webkit and FF
+body {
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ // Font with fallback for body copy
+ --md-text-font-family:
+ var(--md-text-font, _),
+ -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif;
+
+ // Font with fallback for code
+ --md-code-font-family:
+ var(--md-code-font, _),
+ SFMono-Regular, Consolas, Menlo, monospace;
+}
+
+// Define default fonts
+body,
+input,
+aside {
+ font-family: var(--md-text-font-family);
+ font-feature-settings: "kern", "liga";
+ color: var(--md-typeset-color);
+}
+
+// Define monospaced fonts
+code,
+pre,
+kbd {
+ font-family: var(--md-code-font-family);
+ font-feature-settings: "kern";
+}
+
+// ----------------------------------------------------------------------------
+// Rules: typesetted content
+// ----------------------------------------------------------------------------
+
+// General variables
+:root {
+ --md-typeset-table-sort-icon: svg-load("material/sort.svg");
+ --md-typeset-table-sort-icon--asc: svg-load("material/sort-ascending.svg");
+ --md-typeset-table-sort-icon--desc: svg-load("material/sort-descending.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Content that is typeset - if possible, all margins, paddings and font sizes
+// should be set in ems, so nested blocks (e.g. admonitions) render correctly.
+.md-typeset {
+ font-size: px2rem(16px);
+ line-height: 1.6;
+ color-adjust: exact;
+
+ // [print]: We'll use a smaller `font-size` for printing, so code examples
+ // don't break too early, and `16px` looks too big anyway.
+ @media print {
+ font-size: px2rem(13.6px);
+ }
+
+ // Default spacing
+ ul,
+ ol,
+ dl,
+ figure,
+ blockquote,
+ pre {
+ margin-block: 1em;
+ }
+
+ // Headline on level 1
+ h1 {
+ margin: 0 0 px2em(40px, 32px);
+ font-size: px2em(32px);
+ font-weight: 300;
+ line-height: 1.3;
+ color: var(--md-default-fg-color--light);
+ letter-spacing: -0.01em;
+ }
+
+ // Headline on level 2
+ h2 {
+ margin: px2em(40px, 25px) 0 px2em(16px, 25px);
+ font-size: px2em(25px);
+ font-weight: 300;
+ line-height: 1.4;
+ letter-spacing: -0.01em;
+ }
+
+ // Headline on level 3
+ h3 {
+ margin: px2em(32px, 20px) 0 px2em(16px, 20px);
+ font-size: px2em(20px);
+ font-weight: 400;
+ line-height: 1.5;
+ letter-spacing: -0.01em;
+ }
+
+ // Headline on level 3 following level 2
+ h2 + h3 {
+ margin-top: px2em(16px, 20px);
+ }
+
+ // Headline on level 4
+ h4 {
+ margin: px2em(16px) 0;
+ font-weight: 700;
+ letter-spacing: -0.01em;
+ }
+
+ // Headline on level 5-6
+ h5,
+ h6 {
+ margin: px2em(16px, 12.8px) 0;
+ font-size: px2em(12.8px);
+ font-weight: 700;
+ color: var(--md-default-fg-color--light);
+ letter-spacing: -0.01em;
+ }
+
+ // Headline on level 5
+ h5 {
+ text-transform: uppercase;
+ }
+
+ // Horizontal separator
+ hr {
+ display: flow-root;
+ margin: 1.5em 0;
+ border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest);
+ }
+
+ // Text link
+ a {
+ color: var(--md-typeset-a-color);
+ word-break: break-word;
+
+ // Also enable color transition on pseudo elements
+ &,
+ &::before {
+ transition: color 125ms;
+ }
+
+ // Text link on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+
+ // Inline code block
+ code {
+ background-color: var(--md-accent-fg-color--transparent);
+ }
+ }
+
+ // Inline code block
+ code {
+ color: currentcolor;
+ transition: background-color 125ms;
+ }
+
+ // Show outline for keyboard devices
+ &.focus-visible {
+ outline-color: var(--md-accent-fg-color);
+ outline-offset: px2rem(4px);
+ }
+ }
+
+ // Code block
+ code,
+ pre,
+ kbd {
+ font-variant-ligatures: none;
+ color: var(--md-code-fg-color);
+ direction: ltr;
+
+ // [print]: Wrap text and hide scollbars
+ @media print {
+ white-space: pre-wrap;
+ }
+ }
+
+ // Inline code block
+ code {
+ padding: 0 px2em(4px, 13.6px);
+ font-size: px2em(13.6px);
+ word-break: break-word;
+ background-color: var(--md-code-bg-color);
+ border-radius: px2rem(2px);
+ box-decoration-break: clone;
+
+ // Hide outline for pointer devices
+ &:not(.focus-visible) {
+ outline: none;
+ -webkit-tap-highlight-color: transparent;
+ }
+ }
+
+ // Unformatted content
+ pre {
+ position: relative;
+ display: flow-root;
+ line-height: 1.4;
+
+ // Code block
+ > code {
+ display: block;
+ padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px);
+ margin: 0;
+ overflow: auto;
+ word-break: normal;
+ touch-action: auto;
+ outline-color: var(--md-accent-fg-color);
+ box-shadow: none;
+ box-decoration-break: slice;
+ scrollbar-width: thin;
+ scrollbar-color: var(--md-default-fg-color--lighter) transparent;
+
+ // Code block on hover
+ &:hover {
+ scrollbar-color: var(--md-accent-fg-color) transparent;
+ }
+
+ // Webkit scrollbar
+ &::-webkit-scrollbar {
+ width: px2rem(4px);
+ height: px2rem(4px);
+ }
+
+ // Webkit scrollbar thumb
+ &::-webkit-scrollbar-thumb {
+ background-color: var(--md-default-fg-color--lighter);
+
+ // Webkit scrollbar thumb on hover
+ &:hover {
+ background-color: var(--md-accent-fg-color);
+ }
+ }
+ }
+ }
+
+ // Keyboard key
+ kbd {
+ display: inline-block;
+ padding: 0 px2em(8px, 12px);
+ font-size: px2em(12px);
+ color: var(--md-default-fg-color);
+ word-break: break-word;
+ vertical-align: text-top;
+ background-color: var(--md-typeset-kbd-color);
+ border-radius: px2rem(2px);
+ box-shadow:
+ 0 px2rem(2px) 0 px2rem(1px) var(--md-typeset-kbd-border-color),
+ 0 px2rem(2px) 0 var(--md-typeset-kbd-border-color),
+ 0 px2rem(-2px) px2rem(4px) var(--md-typeset-kbd-accent-color) inset;
+ }
+
+ // Text highlighting marker
+ mark {
+ color: inherit;
+ word-break: break-word;
+ background-color: var(--md-typeset-mark-color);
+ box-decoration-break: clone;
+ }
+
+ // Abbreviation
+ abbr {
+ text-decoration: none;
+ cursor: help;
+ border-bottom: px2rem(1px) dotted var(--md-default-fg-color--light);
+
+ // Show tooltip for touch devices
+ @media (hover: none) {
+
+ // Tooltip
+ &[title]:is(:focus, :hover)::after {
+ position: absolute;
+ inset-inline: px2rem(16px);
+ padding: px2rem(4px) px2rem(6px);
+ margin-top: 2em;
+ font-size: px2rem(14px);
+ color: var(--md-default-bg-color);
+ content: attr(title);
+ background-color: var(--md-default-fg-color);
+ border-radius: px2rem(2px);
+ box-shadow: var(--md-shadow-z3);
+ }
+ }
+ }
+
+ // Small text
+ small {
+ opacity: 0.75;
+ }
+
+ // Superscript and subscript
+ sup,
+ sub {
+ margin-inline-start: px2em(1px, 12.8px);
+ }
+
+ // Blockquotes, possibly nested
+ blockquote {
+ padding-inline-start: px2rem(12px);
+ margin-inline: 0;
+ color: var(--md-default-fg-color--light);
+ border-inline-start: px2rem(4px) solid var(--md-default-fg-color--lighter);
+ }
+
+ // Unordered list
+ ul {
+ list-style-type: disc;
+ }
+
+ // Unordered and ordered list
+ ul,
+ ol {
+ padding: 0;
+ margin-inline-start: px2em(10px);
+
+ // Adjust display mode if not hidden
+ &:not([hidden]) {
+ display: flow-root;
+ }
+
+ // Nested ordered list
+ ol {
+ list-style-type: lower-alpha;
+
+ // Triply nested ordered list
+ ol {
+ list-style-type: lower-roman;
+ }
+ }
+
+ // List element
+ li {
+ margin-inline-start: px2em(20px);
+ margin-bottom: 0.5em;
+
+ // Adjust spacing
+ p,
+ blockquote {
+ margin: 0.5em 0;
+ }
+
+ // Adjust spacing on last child
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ // Nested list
+ :is(ul, ol) {
+ margin-block: 0.5em;
+ margin-inline-start: px2em(10px);
+ }
+ }
+ }
+
+ // Definition list
+ dd {
+ margin-block: 1em 1.5em;
+ margin-inline-start: px2em(30px);
+ }
+
+ // Image or video
+ img,
+ svg,
+ video {
+ max-width: 100%;
+ height: auto;
+ }
+
+ // Image
+ img {
+
+ // Adjust spacing when left-aligned
+ &[align="left"] {
+ margin: 1em;
+ margin-left: 0;
+ }
+
+ // Adjust spacing when right-aligned
+ &[align="right"] {
+ margin: 1em;
+ margin-right: 0;
+ }
+
+ // Adjust spacing when sole children
+ &[align]:only-child {
+ margin-top: 0;
+ }
+ }
+
+ // Figure
+ figure {
+ display: flow-root;
+ width: fit-content;
+ max-width: 100%;
+ margin: 1em auto;
+ text-align: center;
+
+ // Figure images
+ img {
+ display: block;
+ }
+ }
+
+ // Figure caption
+ figcaption {
+ max-width: px2rem(480px);
+ margin: 1em auto;
+ font-style: italic;
+ }
+
+ // Limit width to container
+ iframe {
+ max-width: 100%;
+ }
+
+ // Data table
+ table:not([class]) {
+ display: inline-block;
+ max-width: 100%;
+ overflow: auto;
+ font-size: px2rem(12.8px);
+ touch-action: auto;
+ background-color: var(--md-default-bg-color);
+ border: px2rem(1px) solid var(--md-typeset-table-color);
+ border-radius: px2rem(2px);
+
+ // [print]: Reset display mode so table header wraps when printing
+ @media print {
+ display: table;
+ }
+
+ // Due to margin collapse because of the necessary inline-block hack, we
+ // cannot increase the bottom margin on the table, so we just increase the
+ // top margin on the following element
+ + * {
+ margin-top: 1.5em;
+ }
+
+ // Elements in table heading and cell
+ :is(th, td) > * {
+
+ // Adjust spacing on first child
+ &:first-child {
+ margin-top: 0;
+ }
+
+ // Adjust spacing on last child
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ // Table heading and cell
+ :is(th, td):not([align]) {
+ text-align: left;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ text-align: right;
+ }
+ }
+
+ // Table heading
+ th {
+ min-width: px2rem(100px);
+ padding: px2em(12px, 12.8px) px2em(16px, 12.8px);
+ font-weight: 700;
+ vertical-align: top;
+ }
+
+ // Table cell
+ td {
+ padding: px2em(12px, 12.8px) px2em(16px, 12.8px);
+ vertical-align: top;
+ border-top: px2rem(1px) solid var(--md-typeset-table-color);
+ }
+
+ // Table body row
+ tbody tr {
+ transition: background-color 125ms;
+
+ // Table row on hover
+ &:hover {
+ background-color: var(--md-typeset-table-color--light);
+ box-shadow: 0 px2rem(1px) 0 var(--md-default-bg-color) inset;
+ }
+ }
+
+ // Text link in table
+ a {
+ word-break: normal;
+ }
+ }
+
+ // Sortable table
+ table th[role="columnheader"] {
+ cursor: pointer;
+
+ // Sort icon
+ &::after {
+ display: inline-block;
+ width: 1.2em;
+ height: 1.2em;
+ margin-inline-start: 0.5em;
+ vertical-align: text-bottom;
+ content: "";
+ transition: background-color 125ms;
+ mask-image: var(--md-typeset-table-sort-icon);
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+
+ // Show sort icon on hover
+ &:hover::after {
+ background-color: var(--md-default-fg-color--lighter);
+ }
+
+ // Sort ascending icon
+ &[aria-sort="ascending"]::after {
+ background-color: var(--md-default-fg-color--light);
+ mask-image: var(--md-typeset-table-sort-icon--asc);
+ }
+
+ // Sort descending icon
+ &[aria-sort="descending"]::after {
+ background-color: var(--md-default-fg-color--light);
+ mask-image: var(--md-typeset-table-sort-icon--desc);
+ }
+ }
+
+ // Data table scroll wrapper
+ &__scrollwrap {
+ margin: 1em px2rem(-16px);
+ overflow-x: auto;
+ touch-action: auto;
+ }
+
+ // Data table wrapper
+ &__table {
+ display: inline-block;
+ padding: 0 px2rem(16px);
+ margin-bottom: 0.5em;
+
+ // [print]: Reset display mode so table header wraps when printing
+ @media print {
+ display: block;
+ }
+
+ // Data table
+ html & table {
+ display: table;
+ width: 100%;
+ margin: 0;
+ overflow: hidden;
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules: top-level
+// ----------------------------------------------------------------------------
+
+// [mobile -]: Align with body copy
+@include break-to-device(mobile) {
+
+ // Top-level unformatted content
+ .md-content__inner > pre {
+ margin: 1em px2rem(-16px);
+
+ // Code block
+ code {
+ border-radius: 0;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_author.scss b/src/templates/assets/stylesheets/main/components/_author.scss
new file mode 100644
index 00000000..111baf40
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_author.scss
@@ -0,0 +1,86 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Author, i.e., GitHub user
+ .md-author {
+ position: relative;
+ display: block;
+ flex-shrink: 0;
+ width: px2rem(32px);
+ height: px2rem(32px);
+ overflow: hidden;
+ transition:
+ color 125ms,
+ transform 125ms;
+
+ // Author image
+ img {
+ display: block;
+ border-radius: 100%;
+ }
+
+ // More authors
+ &--more {
+ font-size: px2rem(12px);
+ font-weight: 700;
+ line-height: px2rem(32px);
+ color: var(--md-default-fg-color--lighter);
+ text-align: center;
+ background: var(--md-default-fg-color--lightest);
+ }
+
+ // Enlarge image
+ &--long {
+ width: px2rem(48px);
+ height: px2rem(48px);
+ }
+ }
+
+ // Author link
+ a.md-author {
+ transform: scale(1);
+
+ // Author image
+ img {
+ filter: grayscale(100%) opacity(75%);
+ transition: filter 125ms;
+ }
+
+ // Author on focus/hover
+ &:is(:focus, :hover) {
+ z-index: 1;
+ transform: scale(1.1);
+
+ // Author image
+ img {
+ filter: grayscale(0%);
+ }
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_banner.scss b/src/templates/assets/stylesheets/main/components/_banner.scss
new file mode 100644
index 00000000..8fe08c0f
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_banner.scss
@@ -0,0 +1,68 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Banner for announcements and warnings
+.md-banner {
+ overflow: auto;
+ color: var(--md-footer-fg-color);
+ background-color: var(--md-footer-bg-color);
+
+ // [print]: Hide banner
+ @media print {
+ display: none;
+ }
+
+ // Banner with warning
+ &--warning {
+ color: var(--md-warning-fg-color);
+ background-color: var(--md-warning-bg-color);
+ }
+
+ // Banner wrapper
+ &__inner {
+ padding: 0 px2rem(16px);
+ margin: px2rem(12px) auto;
+ font-size: px2rem(14px);
+ }
+
+ // Banner button
+ &__button {
+ float: inline-end;
+ color: inherit;
+ cursor: pointer;
+ transition: opacity 250ms;
+
+ // [no-js]: Hide button
+ .no-js & {
+ display: none;
+ }
+
+ // Button on hover
+ &:hover {
+ opacity: 0.7;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_base.scss b/src/templates/assets/stylesheets/main/components/_base.scss
new file mode 100644
index 00000000..33f834ed
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_base.scss
@@ -0,0 +1,182 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules: base grid and containers
+// ----------------------------------------------------------------------------
+
+// Stretch container to viewport and set base `font-size`
+html {
+ height: 100%;
+ overflow-x: hidden;
+ // Hack: normally, we would set the base `font-size` to `62.5%`, so we can
+ // base all calculations on `10px`, but Chromium and Chrome define a minimal
+ // `font-size` of `12px` if the system language is set to Chinese. For this
+ // reason we just double the `font-size` and set it to `20px`.
+ //
+ // See https://github.com/squidfunk/mkdocs-material/issues/911
+ font-size: 125%;
+
+ // [screen medium +]: Set base `font-size` to `11px`
+ @include break-from-device(screen medium) {
+ font-size: 137.5%;
+ }
+
+ // [screen large +]: Set base `font-size` to `12px`
+ @include break-from-device(screen large) {
+ font-size: 150%;
+ }
+}
+
+// Stretch body to container - flexbox is used, so the footer will always be
+// aligned to the bottom of the viewport
+body {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ min-height: 100%;
+ // Hack: reset `font-size` to `10px`, so the spacing for all inline elements
+ // is correct again. Otherwise the spacing would be based on `20px`.
+ font-size: px2rem(10px);
+ background-color: var(--md-default-bg-color);
+
+ // [print]: Omit flexbox layout due to a Firefox bug (https://mzl.la/39DgR3m)
+ @media print {
+ display: block;
+ }
+
+ // Body in locked state
+ &[data-md-scrolllock] {
+
+ // [tablet portrait -]: Omit scroll bubbling
+ @include break-to-device(tablet portrait) {
+ position: fixed;
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Grid container - this class is applied to wrapper elements within the
+// header, content area and footer, and makes sure that their width is limited
+// to `1220px`, and they are rendered centered if the screen is larger.
+.md-grid {
+ max-width: px2rem(1220px);
+ margin-inline: auto;
+}
+
+// Main container
+.md-container {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+
+ // [print]: Omit flexbox layout due to a Firefox bug (https://mzl.la/39DgR3m)
+ @media print {
+ display: block;
+ }
+}
+
+// Main area - stretch to remaining space of container
+.md-main {
+ flex-grow: 1;
+
+ // Main area wrapper
+ &__inner {
+ display: flex;
+ height: 100%;
+ margin-top: px2rem(24px + 6px);
+ }
+}
+
+// Add ellipsis in case of overflowing text
+.md-ellipsis {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+// ----------------------------------------------------------------------------
+// Rules: navigational elements
+// ----------------------------------------------------------------------------
+
+// Toggle - this class is applied to checkbox elements, which are used to
+// implement the CSS-only drawer and navigation, as well as the search
+.md-toggle {
+ display: none;
+}
+
+// Option - this class is applied to radio elements, which are used to
+// implement the color palette toggle
+.md-option {
+ position: absolute;
+ width: 0;
+ height: 0;
+ opacity: 0;
+
+ // Option label for checked radio button
+ &:checked + label:not([hidden]) {
+ display: block;
+ }
+
+ // Show outline for keyboard devices
+ &.focus-visible + label {
+ outline-style: auto;
+ outline-color: var(--md-accent-fg-color);
+ }
+}
+
+// Skip link
+.md-skip {
+ position: fixed;
+ // Hack: if we don't set the negative `z-index`, the skip link will force the
+ // creation of new layers when code blocks are near the header on scrolling
+ z-index: -1;
+ padding: px2rem(6px) px2rem(10px);
+ margin: px2rem(10px);
+ font-size: px2rem(12.8px);
+ color: var(--md-default-bg-color);
+ background-color: var(--md-default-fg-color);
+ border-radius: px2rem(2px);
+ outline-color: var(--md-accent-fg-color);
+ opacity: 0;
+ transform: translateY(px2rem(8px));
+
+ // Show skip link on focus
+ &:focus {
+ z-index: 10;
+ opacity: 1;
+ transition:
+ transform 250ms cubic-bezier(0.4, 0, 0.2, 1),
+ opacity 175ms 75ms;
+ transform: translateY(0);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules: print styles
+// ----------------------------------------------------------------------------
+
+// Add margins to page
+@page {
+ margin: 25mm;
+}
diff --git a/src/templates/assets/stylesheets/main/components/_clipboard.scss b/src/templates/assets/stylesheets/main/components/_clipboard.scss
new file mode 100644
index 00000000..c07c9c67
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_clipboard.scss
@@ -0,0 +1,102 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Clipboard button variables
+:root {
+ --md-clipboard-icon: svg-load("material/content-copy.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Clipboard button
+.md-clipboard {
+ position: absolute;
+ top: px2em(8px);
+ right: px2em(8px);
+ z-index: 1;
+ width: px2em(24px);
+ height: px2em(24px);
+ color: var(--md-default-fg-color--lightest);
+ cursor: pointer;
+ border-radius: px2rem(2px);
+ outline-color: var(--md-accent-fg-color);
+ outline-offset: px2rem(2px);
+ transition: color 250ms;
+
+ // [print]: Hide button
+ @media print {
+ display: none;
+ }
+
+ // Hide outline for pointer devices
+ &:not(.focus-visible) {
+ outline: none;
+ -webkit-tap-highlight-color: transparent;
+ }
+
+ // Darken color on code block hover
+ :hover > & {
+ color: var(--md-default-fg-color--light);
+ }
+
+ // Button on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ }
+
+ // Button icon - the width and height are defined in `em`, so the size is
+ // automatically adjusted for nested code blocks (e.g. in admonitions)
+ &::after {
+ display: block;
+ width: px2em(18px);
+ height: px2em(18px);
+ margin: 0 auto;
+ content: "";
+ background-color: currentcolor;
+ mask-image: var(--md-clipboard-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+
+ // Inline clipboard button
+ &--inline {
+ cursor: pointer;
+
+ // Code block
+ code {
+ transition:
+ color 250ms,
+ background-color 250ms;
+ }
+
+ // Code block on focus/hover
+ &:is(:focus, :hover) code {
+ color: var(--md-accent-fg-color);
+ background-color: var(--md-accent-fg-color--transparent);
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_consent.scss b/src/templates/assets/stylesheets/main/components/_consent.scss
new file mode 100644
index 00000000..5502460c
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_consent.scss
@@ -0,0 +1,127 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Keyframes
+// ----------------------------------------------------------------------------
+
+// Show consent
+@keyframes consent {
+ 0% {
+ opacity: 0;
+ transform: translateY(100%);
+ }
+
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+// Show consent overlay
+@keyframes overlay {
+ 0% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Consent
+.md-consent {
+
+ // Consent overlay
+ &__overlay {
+ position: fixed;
+ top: 0;
+ z-index: 5;
+ width: 100%;
+ height: 100%;
+ background-color: hsla(0, 0%, 0%, 0.54);
+ opacity: 1;
+ backdrop-filter: blur(px2rem(2px));
+ animation: overlay 250ms both;
+ }
+
+ // Consent wrapper
+ &__inner {
+ position: fixed;
+ bottom: 0;
+ z-index: 5;
+ width: 100%;
+ max-height: 100%;
+ padding: 0;
+ overflow: auto;
+ background-color: var(--md-default-bg-color);
+ border: 0;
+ border-radius: px2rem(2px);
+ box-shadow:
+ 0 0 px2rem(4px) rgba(0, 0, 0, 0.1),
+ 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0.2);
+ animation: consent 500ms cubic-bezier(0.1, 0.7, 0.1, 1) both;
+ }
+
+ // Consent form
+ &__form {
+ padding: px2rem(16px);
+ }
+
+ // Consent settings
+ &__settings {
+ display: none;
+ margin: 1em 0;
+
+ // Show settings
+ input:checked + & {
+ display: block;
+ }
+ }
+
+ // Consent controls
+ &__controls {
+ margin-bottom: px2rem(16px);
+
+ // Consent control button
+ .md-typeset & .md-button {
+ display: inline;
+
+ // [tablet +]: Align buttons horizontally
+ @include break-to-device(mobile) {
+ display: block;
+ width: 100%;
+ margin-top: px2rem(8px);
+ text-align: center;
+ }
+ }
+ }
+
+ // Ensure users realize that labels are clickaböe
+ label {
+ cursor: pointer;
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_content.scss b/src/templates/assets/stylesheets/main/components/_content.scss
new file mode 100644
index 00000000..7c945749
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_content.scss
@@ -0,0 +1,97 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Content area
+.md-content {
+ flex-grow: 1;
+ // Hack: we must use `min-width: 0`, so the content area is capped by the
+ // dimensions of its parent. Otherwise, long code blocks might lead to a
+ // wider content area which will overflow. See https://bit.ly/3bP3f8k
+ min-width: 0;
+
+ // Content wrapper
+ &__inner {
+ padding-top: px2rem(12px);
+ margin: 0 px2rem(16px) px2rem(24px);
+
+ // [screen +]: Adjust spacing between content area and sidebars
+ @include break-from-device(screen) {
+
+ // Sidebar with navigation is visible
+ .md-sidebar--primary:not([hidden]) ~ .md-content > & {
+ margin-inline-start: px2rem(24px);
+ }
+
+ // Sidebar with table of contents is visible
+ .md-sidebar--secondary:not([hidden]) ~ .md-content > & {
+ margin-inline-end: px2rem(24px);
+ }
+ }
+
+ // Hack: add pseudo element for spacing, as the overflow of the content
+ // container may not be hidden due to an imminent offset error on targets
+ &::before {
+ display: block;
+ height: px2rem(8px);
+ content: "";
+ }
+
+ // Adjust spacing on last child
+ > :last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ // Button inside of the content area - these buttons are meant for actions on
+ // a document-level, i.e. linking to related source code files, printing etc.
+ &__button {
+ float: inline-end;
+ padding: 0;
+ margin: px2rem(8px) 0;
+ margin-inline-start: px2rem(8px);
+
+ // [print]: Hide buttons
+ @media print {
+ display: none;
+ }
+
+ // Adjust default link color for icons
+ .md-typeset & {
+ color: var(--md-default-fg-color--lighter);
+ }
+
+ // Align with body copy located next to icon
+ svg {
+ display: inline;
+ vertical-align: top;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: scaleX(-1);
+ }
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_dialog.scss b/src/templates/assets/stylesheets/main/components/_dialog.scss
new file mode 100644
index 00000000..16782ede
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_dialog.scss
@@ -0,0 +1,65 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Dialog
+.md-dialog {
+ position: fixed;
+ bottom: px2rem(16px);
+ z-index: 4;
+ min-width: px2rem(222px);
+ padding: px2rem(8px) px2rem(12px);
+ pointer-events: none;
+ background-color: var(--md-default-fg-color);
+ border-radius: px2rem(2px);
+ box-shadow: var(--md-shadow-z3);
+ opacity: 0;
+ transition:
+ transform 0ms 400ms,
+ opacity 400ms;
+ transform: translateY(100%);
+ inset-inline-end: px2rem(16px);
+
+ // [print]: Hide dialog
+ @media print {
+ display: none;
+ }
+
+ // Active dialog
+ &--active {
+ pointer-events: initial;
+ opacity: 1;
+ transition:
+ transform 400ms cubic-bezier(0.075, 0.85, 0.175, 1),
+ opacity 400ms;
+ transform: translateY(0);
+ }
+
+ // Dialog wrapper
+ &__inner {
+ font-size: px2rem(14px);
+ color: var(--md-default-bg-color);
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_feedback.scss b/src/templates/assets/stylesheets/main/components/_feedback.scss
new file mode 100644
index 00000000..bbcd00e9
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_feedback.scss
@@ -0,0 +1,110 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Was this page helpful?
+.md-feedback {
+ margin: 2em 0 1em;
+ text-align: center;
+
+ // Feedback fieldset
+ fieldset {
+ padding: 0;
+ margin: 0;
+ border: none;
+ }
+
+ // Feedback title
+ &__title {
+ margin: 1em auto;
+ font-weight: 700;
+ }
+
+ // Feedback wrapper
+ &__inner {
+ position: relative;
+ }
+
+ // Feedback list
+ &__list {
+ position: relative;
+ display: flex;
+ flex-wrap: wrap;
+ align-content: baseline;
+ justify-content: center;
+
+ // Feedback icon on hover
+ &:hover .md-icon:not(:disabled) {
+ color: var(--md-default-fg-color--lighter);
+ }
+
+ // Adjust height after submission
+ :disabled & {
+ min-height: px2rem(36px);
+ }
+ }
+
+ // Feedback icon
+ &__icon {
+ flex-shrink: 0;
+ margin: 0 px2rem(2px);
+ color: var(--md-default-fg-color--light);
+ cursor: pointer;
+ transition: color 125ms;
+
+ // Feedback icon on hover
+ &:not(:disabled).md-icon:hover {
+ color: var(--md-accent-fg-color);
+ }
+
+ // Feedback icon after submit
+ &:disabled {
+ color: var(--md-default-fg-color--lightest);
+ pointer-events: none;
+ }
+ }
+
+ // Feedback note
+ &__note {
+ position: relative;
+ opacity: 0;
+ transition:
+ transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ opacity 150ms;
+ transform: translateY(px2rem(8px));
+
+ // Feedback note value
+ > * {
+ max-width: px2rem(320px);
+ margin: 0 auto;
+ }
+
+ // Show after submission
+ :disabled & {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_footer.scss b/src/templates/assets/stylesheets/main/components/_footer.scss
new file mode 100644
index 00000000..9fabc05b
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_footer.scss
@@ -0,0 +1,201 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Footer
+.md-footer {
+ color: var(--md-footer-fg-color);
+ background-color: var(--md-footer-bg-color);
+
+ // [print]: Hide footer
+ @media print {
+ display: none;
+ }
+
+ // Footer wrapper
+ &__inner {
+ justify-content: space-between;
+ padding: px2rem(4px);
+ overflow: auto;
+
+ // Footer is visible
+ &:not([hidden]) {
+ display: flex;
+ }
+ }
+
+ // Footer link to previous and next page
+ &__link {
+ display: flex;
+ // Hack: some browsers induce ellipsis on flex children that are set to
+ // `overflow: hidden` and `text-overflow: ellipsis`. Enforcing growth by
+ // a tiny factor seems to get rid of the ellipsis and renders the text as
+ // it should - see https://bit.ly/2ZUCXQ8
+ flex-grow: 0.01;
+ align-items: end;
+ max-width: 100%;
+ margin-block: px2rem(20px) px2rem(8px);
+ overflow: hidden;
+ outline-color: var(--md-accent-fg-color);
+ transition: opacity 250ms;
+
+ // Footer link on focus/hover
+ &:is(:focus, :hover) {
+ opacity: 0.7;
+ }
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & svg {
+ transform: scaleX(-1);
+ }
+
+ // [mobile -]: Adjust width to 25/75 and hide title
+ @include break-to-device(mobile) {
+
+ // Footer link to previous page
+ &--prev {
+ flex-shrink: 0;
+
+ // Hide footer title
+ .md-footer__title {
+ display: none;
+ }
+ }
+ }
+
+ // Footer link to next page
+ &--next {
+ margin-inline-start: auto;
+ text-align: right;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ text-align: left;
+ }
+ }
+ }
+
+ // Footer title
+ &__title {
+ flex-grow: 1;
+ max-width: calc(100% - #{px2rem(48px)});
+ padding: 0 px2rem(20px);
+ margin-bottom: px2rem(14px);
+ font-size: px2rem(18px);
+ white-space: nowrap;
+ }
+
+ // Footer link button
+ &__button {
+ padding: px2rem(8px);
+ margin: px2rem(4px);
+ }
+
+ // Footer link direction (i.e. prev and next)
+ &__direction {
+ font-size: px2rem(12.8px);
+ opacity: 0.7;
+ }
+}
+
+// Footer metadata
+.md-footer-meta {
+ background-color: var(--md-footer-bg-color--dark);
+
+ // Footer metadata wrapper
+ &__inner {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ padding: px2rem(4px);
+ }
+
+ // Lighten color for non-hovered text links
+ html &.md-typeset a {
+ color: var(--md-footer-fg-color--light);
+
+ // Text link on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-footer-fg-color);
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Copyright and theme information
+.md-copyright {
+ width: 100%;
+ padding: px2rem(8px) 0;
+ margin: auto px2rem(12px);
+ font-size: px2rem(12.8px);
+ color: var(--md-footer-fg-color--lighter);
+
+ // [tablet portrait +]: Show copyright and social links in one line
+ @include break-from-device(tablet portrait) {
+ width: auto;
+ }
+
+ // Footer copyright highlight - this is the upper part of the copyright and
+ // theme information, which will include a darker color than the theme link
+ &__highlight {
+ color: var(--md-footer-fg-color--light);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Social links
+.md-social {
+ display: inline-flex;
+ gap: px2rem(4px);
+ padding: px2rem(4px) 0 px2rem(12px);
+ margin: 0 px2rem(8px);
+
+ // [tablet portrait +]: Show copyright and social links in one line
+ @include break-from-device(tablet portrait) {
+ padding: px2rem(12px) 0;
+ }
+
+ // Footer social link
+ &__link {
+ display: inline-block;
+ width: px2rem(32px);
+ height: px2rem(32px);
+ text-align: center;
+
+ // Adjust line-height to match height for correct alignment
+ &::before {
+ line-height: 1.9;
+ }
+
+ // Fill icon with current color
+ svg {
+ max-height: px2rem(16px);
+ vertical-align: -25%;
+ fill: currentcolor;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_form.scss b/src/templates/assets/stylesheets/main/components/_form.scss
new file mode 100644
index 00000000..49b59e42
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_form.scss
@@ -0,0 +1,83 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Form button
+ .md-button {
+ display: inline-block;
+ padding: px2em(10px) px2em(32px);
+ font-weight: 700;
+ color: var(--md-primary-fg-color);
+ cursor: pointer;
+ border: px2rem(2px) solid currentcolor;
+ border-radius: px2rem(2px);
+ transition:
+ color 125ms,
+ background-color 125ms,
+ border-color 125ms;
+
+ // Primary button
+ &--primary {
+ color: var(--md-primary-bg-color);
+ background-color: var(--md-primary-fg-color);
+ border-color: var(--md-primary-fg-color);
+ }
+
+ // Button on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-bg-color);
+ background-color: var(--md-accent-fg-color);
+ border-color: var(--md-accent-fg-color);
+ }
+ }
+
+ // Form input
+ .md-input {
+ height: px2rem(36px);
+ padding: 0 px2rem(12px);
+ font-size: px2rem(16px);
+ border-bottom: px2rem(2px) solid var(--md-default-fg-color--lighter);
+ border-start-start-radius: px2rem(2px);
+ border-start-end-radius: px2rem(2px);
+ box-shadow: var(--md-shadow-z1);
+ transition:
+ border 250ms,
+ box-shadow 250ms;
+
+ // Input on focus/hover
+ &:is(:focus, :hover) {
+ border-bottom-color: var(--md-accent-fg-color);
+ box-shadow: var(--md-shadow-z2);
+ }
+
+ // Stretch to full width
+ &--stretch {
+ width: 100%;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_header.scss b/src/templates/assets/stylesheets/main/components/_header.scss
new file mode 100644
index 00000000..e51f3f99
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_header.scss
@@ -0,0 +1,270 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Header - by default, the header will be sticky and stay always on top of the
+// viewport. If this behavior is not desired, just set `position: static`.
+.md-header {
+ position: sticky;
+ inset-inline: 0;
+ top: 0;
+ z-index: 4;
+ display: block;
+ color: var(--md-primary-bg-color);
+ background-color: var(--md-primary-fg-color);
+ // Hack: reduce jitter by adding a transparent box shadow of the same size
+ // so the size of the layer doesn't change during animation
+ box-shadow:
+ 0 0 px2rem(4px) rgba(0, 0, 0, 0),
+ 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0);
+
+ // [print]: Hide header
+ @media print {
+ display: none;
+ }
+
+ // Header is hidden
+ &[hidden] {
+ transition:
+ transform 250ms cubic-bezier(0.8, 0, 0.6, 1),
+ box-shadow 250ms;
+ transform: translateY(-100%);
+ }
+
+ // Header in shadow state, i.e. shadow is visible
+ &--shadow {
+ box-shadow:
+ 0 0 px2rem(4px) rgba(0, 0, 0, 0.1),
+ 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0.2);
+ transition:
+ transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ box-shadow 250ms;
+ }
+
+ // Header wrapper
+ &__inner {
+ display: flex;
+ align-items: center;
+ padding: 0 px2rem(4px);
+ }
+
+ // Header button
+ &__button {
+ position: relative;
+ z-index: 1;
+ padding: px2rem(8px);
+ margin: px2rem(4px);
+ color: currentcolor;
+ vertical-align: middle;
+ cursor: pointer;
+ outline-color: var(--md-accent-fg-color);
+ transition: opacity 250ms;
+
+ // Button on hover
+ &:hover {
+ opacity: 0.7;
+ }
+
+ // Header button is visible
+ &:not([hidden]) {
+ display: inline-block;
+ }
+
+ // Hide outline for pointer devices
+ &:not(.focus-visible) {
+ outline: none;
+ -webkit-tap-highlight-color: transparent;
+ }
+
+ // Button with logo, pointing to `config.site_url`
+ &.md-logo {
+ padding: px2rem(8px);
+ margin: px2rem(4px);
+
+ // [tablet -]: Hide button
+ @include break-to-device(tablet) {
+ display: none;
+ }
+
+ // Image or icon
+ :is(img, svg) {
+ display: block;
+ width: auto;
+ height: px2rem(24px);
+ fill: currentcolor;
+ }
+ }
+
+ // Button for search
+ &[for="__search"] {
+
+ // [tablet landscape +]: Hide button
+ @include break-from-device(tablet landscape) {
+ display: none;
+ }
+
+ // [no-js]: Hide button
+ .no-js & {
+ display: none;
+ }
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & svg {
+ transform: scaleX(-1);
+ }
+ }
+
+ // Button for drawer
+ &[for="__drawer"] {
+
+ // [screen +]: Hide button
+ @include break-from-device(screen) {
+ display: none;
+ }
+ }
+ }
+
+ // Header topic
+ &__topic {
+ position: absolute;
+ display: flex;
+ max-width: 100%;
+ white-space: nowrap;
+ transition:
+ transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ opacity 150ms;
+
+ // Second header topic - title of the current page
+ & + & {
+ z-index: -1;
+ pointer-events: none;
+ opacity: 0;
+ transition:
+ transform 400ms cubic-bezier(1, 0.7, 0.1, 0.1),
+ opacity 150ms;
+ transform: translateX(px2rem(25px));
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: translateX(px2rem(-25px));
+ }
+ }
+
+ // Adjust font weight of site title
+ &:first-child {
+ font-weight: 700;
+ }
+ }
+
+ // Header title
+ &__title {
+ flex-grow: 1;
+ height: px2rem(48px);
+ margin-inline-start: px2rem(20px);
+ margin-inline-end: px2rem(8px);
+ font-size: px2rem(18px);
+ line-height: px2rem(48px);
+
+ // Header title in active state, i.e. page title is visible
+ &--active .md-header__topic {
+ z-index: -1;
+ pointer-events: none;
+ opacity: 0;
+ transition:
+ transform 400ms cubic-bezier(1, 0.7, 0.1, 0.1),
+ opacity 150ms;
+ transform: translateX(px2rem(-25px));
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: translateX(px2rem(25px));
+ }
+
+ // Second header topic - title of the current page
+ + .md-header__topic {
+ z-index: 0;
+ pointer-events: initial;
+ opacity: 1;
+ transition:
+ transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ opacity 150ms;
+ transform: translateX(0);
+ }
+ }
+
+ // Add ellipsis in case of overflowing text
+ > .md-header__ellipsis {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ }
+ }
+
+ // Header option
+ &__option {
+ display: flex;
+ flex-shrink: 0;
+ max-width: 100%;
+ white-space: nowrap;
+ transition:
+ max-width 0ms 250ms,
+ opacity 250ms 250ms;
+
+ // Hide toggle when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ max-width: 0;
+ opacity: 0;
+ transition:
+ max-width 0ms,
+ opacity 0ms;
+ }
+
+ // Hack: Firefox 117 introduces a bug where the browser scrolls the page by
+ // a small amount to the top every time the header button is focused. After
+ // investigating, we're confident that it seems to be caused by the input
+ // field being too close to the border - see https://t.ly/APO8l
+ > input {
+ bottom: 0;
+ }
+ }
+
+ // Repository information container
+ &__source {
+ display: none;
+
+ // [tablet landscape +]: Show repository information
+ @include break-from-device(tablet landscape) {
+ display: block;
+ width: px2rem(234px);
+ max-width: px2rem(234px);
+ margin-inline-start: px2rem(20px);
+ }
+
+ // [screen +]: Adjust spacing of search bar
+ @include break-from-device(screen) {
+ margin-inline-start: px2rem(28px);
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_meta.scss b/src/templates/assets/stylesheets/main/components/_meta.scss
new file mode 100644
index 00000000..aaeae8df
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_meta.scss
@@ -0,0 +1,67 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Metadata
+.md-meta {
+ font-size: px2rem(14px);
+ line-height: 1.3;
+ color: var(--md-default-fg-color--light);
+
+ // Metadata list
+ &__list {
+ display: inline-flex;
+ flex-wrap: wrap;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ }
+
+ // Metadata item separator
+ &__item:not(:last-child)::after {
+ margin-inline: px2rem(4px);
+ content: "·";
+ }
+
+ // Metadata link
+ &__link {
+ color: var(--md-typeset-a-color);
+
+ // Metadata link on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ }
+ }
+}
+
+// Draft
+.md-draft {
+ display: inline-block;
+ padding-inline: px2em(8px, 14px);
+ font-weight: 700;
+ color: hsla(255, 100%, 100%);
+ background-color: $clr-red-a400;
+ border-radius: px2em(2px);
+}
diff --git a/src/templates/assets/stylesheets/main/components/_nav.scss b/src/templates/assets/stylesheets/main/components/_nav.scss
new file mode 100644
index 00000000..673918af
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_nav.scss
@@ -0,0 +1,761 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Navigation variables
+:root {
+ --md-nav-icon--prev: svg-load("material/arrow-left.svg");
+ --md-nav-icon--next: svg-load("material/chevron-right.svg");
+ --md-toc-icon: svg-load("material/table-of-contents.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Navigation
+.md-nav {
+ font-size: px2rem(14px);
+ line-height: 1.3;
+
+ // Navigation title
+ &__title {
+ display: block;
+ padding: 0 px2rem(12px);
+ overflow: hidden;
+ font-weight: 700;
+ color: var(--md-default-fg-color--light);
+ text-overflow: ellipsis;
+
+ // Navigaton button
+ .md-nav__button {
+ display: none;
+
+ // Stretch images based on height, as it's the smaller dimension
+ img {
+ width: auto;
+ height: 100%;
+ }
+
+ // Button with logo, pointing to `config.site_url`
+ &.md-logo {
+
+ // Image or icon
+ :is(img, svg) {
+ display: block;
+ width: auto;
+ max-width: 100%;
+ height: px2rem(48px);
+ object-fit: contain;
+ fill: currentcolor;
+ }
+ }
+ }
+ }
+
+ // Navigation list
+ &__list {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ }
+
+ // Navigation link
+ &__link {
+ display: flex;
+ gap: px2rem(8px);
+ align-items: flex-start;
+ margin-top: 0.625em;
+ transition: color 125ms;
+ scroll-snap-align: start;
+
+ // Navigation link that was passed
+ &--passed {
+ color: var(--md-default-fg-color--light);
+ }
+
+ // Active link
+ .md-nav__item &--active {
+
+ // Also enable color transitions on inline code blocks
+ &,
+ code {
+ color: var(--md-typeset-a-color);
+ }
+ }
+
+ // Navigation link title
+ .md-ellipsis {
+ // Hack: Safari exhibits a bug where the text will sometimes disappear
+ // and the element will become unclickable. Setting `position: relative`
+ // seems to fix the issue - see https://bit.ly/3HljM1T
+ position: relative;
+ }
+
+ // Always align navigation icons to the end
+ .md-icon:last-child {
+ margin-inline-start: auto;
+ }
+
+ // Navigation link icon
+ svg {
+ flex-shrink: 0;
+ height: 1.3em;
+ fill: currentcolor;
+ }
+
+ // Navigation link on focus/hover
+ &:is([href], [for]):is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ cursor: pointer;
+ }
+
+ // Show outline for keyboard devices
+ &.focus-visible {
+ outline-color: var(--md-accent-fg-color);
+ outline-offset: px2rem(4px);
+ }
+
+ // Navigation link for table of contents
+ .md-nav--primary &[for="__toc"] {
+ display: none;
+
+ // Table of contents icon
+ .md-icon::after {
+ display: block;
+ width: 100%;
+ height: 100%;
+ mask-image: var(--md-toc-icon);
+ background-color: currentcolor;
+ }
+
+ // Hide table of contents
+ ~ .md-nav {
+ display: none;
+ }
+ }
+ }
+
+ // Navigation container (for section index pages)
+ &__container > .md-nav__link {
+ margin-top: 0;
+
+ // Stretch first child
+ &:first-child {
+ flex-grow: 1;
+ // Hack: if a very long word is used, it can push the arrow out of sight.
+ // Setting this property contains the text - see https://t.ly/E02vp
+ min-width: 0;
+ }
+ }
+
+ // Navigation icon
+ &__icon {
+ flex-shrink: 0;
+ }
+
+ // Repository information container
+ &__source {
+ display: none;
+ }
+
+ // [tablet -]: Layered navigation
+ @include break-to-device(tablet) {
+
+ // Primary and nested navigation
+ &--primary,
+ &--primary & {
+ position: absolute;
+ inset-inline: 0;
+ top: 0;
+ z-index: 1;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ background-color: var(--md-default-bg-color);
+ }
+
+ // Primary navigation
+ &--primary {
+
+ // Navigation title and item
+ :is(.md-nav__title, .md-nav__item) {
+ font-size: px2rem(16px);
+ line-height: 1.5;
+ }
+
+ // Navigation title
+ .md-nav__title {
+ position: relative;
+ height: px2rem(112px);
+ padding: px2rem(60px) px2rem(16px) px2rem(4px);
+ line-height: px2rem(48px);
+ color: var(--md-default-fg-color--light);
+ white-space: nowrap;
+ cursor: pointer;
+ background-color: var(--md-default-fg-color--lightest);
+
+ // Navigation icon
+ .md-nav__icon {
+ position: absolute;
+ top: px2rem(8px);
+ inset-inline-start: px2rem(8px);
+ display: block;
+ width: px2rem(24px);
+ height: px2rem(24px);
+ margin: px2rem(4px);
+
+ // Navigation icon in link to previous level
+ &::after {
+ display: block;
+ width: 100%;
+ height: 100%;
+ content: "";
+ background-color: currentcolor;
+ mask-image: var(--md-nav-icon--prev);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+ }
+
+ // Navigation list
+ ~ .md-nav__list {
+ overflow-y: auto;
+ touch-action: pan-y;
+ background-color: var(--md-default-bg-color);
+ box-shadow:
+ 0 px2rem(1px) 0 var(--md-default-fg-color--lightest) inset;
+ scroll-snap-type: y mandatory;
+
+ // Omit border on first child
+ > :first-child {
+ border-top: 0;
+ }
+ }
+
+ // Top-level navigation title
+ &[for="__drawer"] {
+ font-weight: 700;
+ color: var(--md-primary-bg-color);
+ background-color: var(--md-primary-fg-color);
+ }
+
+ // Button with logo, pointing to `config.site_url`
+ .md-logo {
+ position: absolute;
+ inset-inline: px2rem(4px);
+ top: px2rem(4px);
+ display: block;
+ padding: px2rem(8px);
+ margin: px2rem(4px);
+ }
+ }
+
+ // Navigation list
+ .md-nav__list {
+ flex: 1;
+ }
+
+ // Navigation item
+ .md-nav__item {
+ border-top: px2rem(1px) solid var(--md-default-fg-color--lightest);
+
+ // Navigation link in active navigation
+ &--active > .md-nav__link {
+ color: var(--md-typeset-a-color);
+
+ // Navigation link on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ }
+ }
+ }
+
+ // Navigation link
+ .md-nav__link {
+ padding: px2rem(12px) px2rem(16px);
+ margin-top: 0;
+
+ // Navigation link icon
+ svg {
+ margin-top: 0.1em;
+ }
+
+ // Adjust spacing on nested link
+ > .md-nav__link {
+ padding: 0;
+ }
+
+ // Navigation icon
+ .md-nav__icon {
+ width: px2rem(24px);
+ height: px2rem(24px);
+ margin-inline-end: px2rem(-4px);
+ font-size: px2rem(24px);
+
+ // Navigation icon in link to next level
+ &::after {
+ display: block;
+ width: 100%;
+ height: 100%;
+ content: "";
+ background-color: currentcolor;
+ mask-image: var(--md-nav-icon--next);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+ }
+ }
+
+ // Flip icon vertically
+ .md-nav__icon {
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] &::after {
+ transform: scale(-1);
+ }
+ }
+
+ // Table of contents contained in primary navigation
+ .md-nav--secondary {
+
+ // Navigation on level 2-6
+ .md-nav {
+ position: static;
+ background-color: transparent;
+
+ // Navigation link on level 3
+ .md-nav__link {
+ padding-inline-start: px2rem(28px);
+ }
+
+ // Navigation link on level 4
+ .md-nav .md-nav__link {
+ padding-inline-start: px2rem(40px);
+ }
+
+ // Navigation link on level 5
+ .md-nav .md-nav .md-nav__link {
+ padding-inline-start: px2rem(52px);
+ }
+
+ // Navigation link on level 6
+ .md-nav .md-nav .md-nav .md-nav__link {
+ padding-inline-start: px2rem(64px);
+ }
+ }
+ }
+ }
+
+ // Table of contents
+ &--secondary {
+ background-color: transparent;
+ }
+
+ // Hide nested navigation
+ &__toggle ~ & {
+ display: flex;
+ opacity: 0;
+ transition:
+ transform 250ms cubic-bezier(0.8, 0, 0.6, 1),
+ opacity 125ms 50ms;
+ transform: translateX(100%);
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: translateX(-100%);
+ }
+ }
+
+ // Show nested navigation when toggle is active
+ &__toggle:checked ~ & {
+ opacity: 1;
+ transition:
+ transform 250ms cubic-bezier(0.4, 0, 0.2, 1),
+ opacity 125ms 125ms;
+ transform: translateX(0);
+
+ // Navigation list
+ > .md-nav__list {
+ // Hack: promote to own layer to reduce jitter
+ backface-visibility: hidden;
+ }
+ }
+ }
+
+ // [tablet portrait -]: Layered navigation with table of contents
+ @include break-to-device(tablet portrait) {
+
+ // Show link to table of contents
+ &--primary &__link[for="__toc"] {
+ display: flex;
+
+ // Show table of contents icon
+ .md-icon::after {
+ content: "";
+ }
+
+ // Hide navigation link to current page
+ + .md-nav__link {
+ display: none;
+ }
+
+ // Show table of contents
+ ~ .md-nav {
+ display: flex;
+ }
+ }
+
+ // Repository information container
+ &__source {
+ display: block;
+ padding: 0 px2rem(4px);
+ color: var(--md-primary-bg-color);
+ background-color: var(--md-primary-fg-color--dark);
+ }
+ }
+
+ // [tablet landscape]: Layered navigation with table of contents
+ @include break-at-device(tablet landscape) {
+
+ // Show link to integrated table of contents
+ &--integrated &__link[for="__toc"] {
+ display: flex;
+
+ // Show table of contents icon
+ .md-icon::after {
+ content: "";
+ }
+
+ // Hide navigation link to current page
+ + .md-nav__link {
+ display: none;
+ }
+
+ // Show table of contents
+ ~ .md-nav {
+ display: flex;
+ }
+ }
+ }
+
+ // [tablet landscape +]: Tree-like table of contents
+ @include break-from-device(tablet landscape) {
+ margin-bottom: px2rem(-8px);
+
+ // Table of contents
+ &--secondary {
+
+ // Navigation title
+ .md-nav__title {
+ position: sticky;
+ top: 0;
+ // Hack: because of the hack that we need to make .md-ellipsis work in
+ // Safari, we need to set `z-index` here as - see https://bit.ly/3s5M2jm
+ z-index: 1;
+ background: var(--md-default-bg-color);
+ box-shadow: 0 0 px2rem(8px) px2rem(8px) var(--md-default-bg-color);
+
+ // Adjust snapping behavior
+ &[for="__toc"] {
+ scroll-snap-align: start;
+ }
+
+ // Hide navigation icon
+ .md-nav__icon {
+ display: none;
+ }
+ }
+
+ // Adjust spacing for navigation list - same reason as below
+ .md-nav__list {
+ padding-inline-start: px2rem(12px);
+ padding-bottom: px2rem(8px);
+ }
+
+ // Adjust spacing for navigation link - before this change, we set spacing
+ // on the left and right of a navigation item, but this led to the problem
+ // of cropped focus outlines, because we must set `overflow: hidden` on
+ // the navigation list for smooth expand and collapse transitions.
+ .md-nav__item > .md-nav__link {
+ margin-inline-end: px2rem(8px);
+ }
+ }
+ }
+
+ // [screen +]: Tree-like navigation
+ @include break-from-device(screen) {
+ margin-bottom: px2rem(-8px);
+ transition: max-height 250ms cubic-bezier(0.86, 0, 0.07, 1);
+
+ // Primary navigation
+ &--primary {
+
+ // Navigation title
+ .md-nav__title {
+ position: sticky;
+ top: 0;
+ // Hack: because of the hack that we need to make .md-ellipsis work in
+ // Safari, we need to set `z-index` here as - see https://bit.ly/3s5M2jm
+ z-index: 1;
+ background: var(--md-default-bg-color);
+ box-shadow: 0 0 px2rem(8px) px2rem(8px) var(--md-default-bg-color);
+
+ // Adjust snapping behavior
+ &[for="__drawer"] {
+ scroll-snap-align: start;
+ }
+
+ // Hide navigation icon
+ .md-nav__icon {
+ display: none;
+ }
+ }
+
+ // Adjust spacing for navigation list - same reason as below
+ .md-nav__list {
+ padding-inline-start: px2rem(12px);
+ padding-bottom: px2rem(8px);
+ }
+
+ // Adjust spacing for navigation link - before this change, we set spacing
+ // on the left and right of a navigation item, but this led to the problem
+ // of cropped focus outlines, because we must set `overflow: hidden` on
+ // the navigation list for smooth expand and collapse transitions.
+ .md-nav__item > .md-nav__link {
+ margin-inline-end: px2rem(8px);
+ }
+ }
+
+ // Hide nested navigation
+ &__toggle ~ & {
+ display: grid;
+ grid-template-rows: 0fr;
+ visibility: collapse;
+ opacity: 0;
+ transition:
+ grid-template-rows 250ms cubic-bezier(0.86, 0, 0.07, 1),
+ opacity 250ms,
+ visibility 0ms 250ms;
+
+ // Navigation list
+ > .md-nav__list {
+ overflow: hidden;
+ }
+ }
+
+ // Show nested navigation when toggle is active or indeterminate
+ &__toggle:is(:checked, :indeterminate) ~ & {
+ grid-template-rows: 1fr;
+ visibility: visible;
+ opacity: 1;
+ transition:
+ grid-template-rows 250ms cubic-bezier(0.86, 0, 0.07, 1),
+ opacity 150ms 100ms,
+ visibility 0ms;
+ }
+
+ // Hide navigation title in nested navigation
+ &__item--nested > & > &__title {
+ display: none;
+ }
+
+ // Navigation section
+ &__item--section {
+ display: block;
+ margin: 1.25em 0;
+
+ // Adjust spacing on last child
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ // Show navigation link as title
+ > .md-nav__link {
+ font-weight: 700;
+
+ // Make labels discernable from links
+ &[for] {
+ color: var(--md-default-fg-color--light);
+ }
+
+ // Omit clicks if not a section index page
+ &:not(.md-nav__container) {
+ pointer-events: none;
+ }
+
+ // Hide navigation icon
+ > [for],
+ .md-icon {
+ display: none;
+ }
+ }
+
+ // Navigation
+ > .md-nav {
+ display: block;
+ margin-inline-start: px2rem(-12px);
+ visibility: visible;
+ opacity: 1;
+
+ // Adjust spacing on next level item
+ > .md-nav__list > .md-nav__item {
+ padding: 0;
+ }
+ }
+ }
+
+ // Navigation icon
+ &__icon {
+ width: px2rem(18px);
+ height: px2rem(18px);
+ border-radius: 100%;
+ transition: background-color 250ms;
+
+ // Navigation icon on hover
+ &:hover {
+ background-color: var(--md-accent-fg-color--transparent);
+ }
+
+ // Navigation icon content
+ &::after {
+ display: inline-block;
+ width: 100%;
+ height: 100%;
+ vertical-align: px2rem(-2px);
+ content: "";
+ background-color: currentcolor;
+ border-radius: 100%;
+ transition: transform 250ms;
+ mask-image: var(--md-nav-icon--next);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: rotate(180deg);
+ }
+
+ // Navigation icon - rotate icon when toggle is active or indeterminate
+ .md-nav__item--nested .md-nav__toggle:checked ~ .md-nav__link &,
+ .md-nav__item--nested .md-nav__toggle:indeterminate ~ .md-nav__link & {
+ transform: rotate(90deg);
+ }
+ }
+ }
+
+ // Modifier for when navigation tabs are rendered
+ &--lifted {
+
+ // Hide site title
+ > .md-nav__title {
+ display: none;
+ }
+
+ // Hide level 0 navigation items
+ > .md-nav__list > .md-nav__item {
+ display: none;
+
+ // Active parent navigation item
+ &--active {
+ display: block;
+
+ // Show navigation link as title
+ > .md-nav__link {
+ position: sticky;
+ top: 0;
+ z-index: 1;
+ margin-top: 0;
+ background: var(--md-default-bg-color);
+ box-shadow: 0 0 px2rem(8px) px2rem(8px) var(--md-default-bg-color);
+
+ // Omit clicks if not a section index page
+ &:not(.md-nav__container) {
+ pointer-events: none;
+ }
+ }
+
+ // Adjust spacing for navigation section
+ &.md-nav__item--section {
+ margin: 0;
+ }
+ }
+
+ // Adjust spacing for nested navigation
+ > .md-nav {
+ margin-inline-start: px2rem(-12px);
+ }
+
+ // Make labels discernable from links
+ > [for] {
+ color: var(--md-default-fg-color--light);
+ }
+ }
+
+ // Hack: Always show active navigation tab on breakpoint screen, despite
+ // of checkbox being checked or not - see https://t.ly/Qc311
+ .md-nav[data-md-level="1"] {
+ grid-template-rows: 1fr;
+ visibility: visible;
+ opacity: 1;
+ }
+ }
+
+ // Modifier for when table of contents is rendered in primary navigation
+ &--integrated > .md-nav__list > .md-nav__item--active {
+
+ // Add spacing to container for non-nested navigation items
+ &:not(.md-nav__item--nested) {
+ padding: 0 px2rem(12px);
+
+ // Remove padding as it's given by container
+ > .md-nav__link {
+ padding: 0;
+ }
+ }
+
+ // Show integrated table of contents
+ .md-nav--secondary {
+ display: block;
+ margin-bottom: 1.25em;
+ visibility: visible;
+ border-inline-start: px2rem(1px) solid var(--md-primary-fg-color);
+ opacity: 1;
+
+ // Navigation list
+ > .md-nav__list {
+ padding-bottom: 0;
+ overflow: visible;
+ }
+
+ // Hide table of contents title
+ > .md-nav__title {
+ display: none;
+ }
+ }
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_pagination.scss b/src/templates/assets/stylesheets/main/components/_pagination.scss
new file mode 100644
index 00000000..a010bf43
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_pagination.scss
@@ -0,0 +1,85 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Pagination
+.md-pagination {
+ display: flex;
+ gap: px2rem(8px);
+ align-items: center;
+ justify-content: center;
+ font-size: px2rem(16px);
+ font-weight: 700;
+
+ // Pagination item
+ > * {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-width: px2rem(36px);
+ height: px2rem(36px);
+ text-align: center;
+ border-radius: px2rem(4px);
+ }
+
+ // Active pagination item
+ &__current {
+ color: var(--md-default-fg-color--light);
+ background-color: var(--md-default-fg-color--lightest);
+ }
+
+ // Pagination link
+ &__link {
+ transition:
+ color 125ms,
+ background-color 125ms;
+
+ // Pagination link on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ background-color: var(--md-accent-fg-color--transparent);
+
+ // Pagination icon
+ svg {
+ color: var(--md-accent-fg-color);
+ }
+ }
+
+ // Show outline for keyboard devices
+ &.focus-visible {
+ outline-color: var(--md-accent-fg-color);
+ outline-offset: px2rem(4px);
+ }
+
+ // Pagination icon
+ svg {
+ display: block;
+ width: px2rem(24px);
+ max-height: 100%;
+ color: var(--md-default-fg-color--lighter);
+ fill: currentcolor;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_post.scss b/src/templates/assets/stylesheets/main/components/_post.scss
new file mode 100644
index 00000000..cf6ce019
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_post.scss
@@ -0,0 +1,196 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Post
+.md-post {
+
+ // Post backlink
+ &__back {
+ padding-bottom: px2rem(24px);
+ margin-bottom: px2rem(24px);
+ border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest);
+
+ // [tablet -]: Hide post backlink
+ @include break-to-device(tablet) {
+ display: none;
+ }
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+
+ // Flip icon vertically
+ svg {
+ transform: scaleX(-1);
+ }
+ }
+ }
+
+ // Post authors
+ &__authors {
+ display: flex;
+ flex-direction: column;
+ gap: px2rem(12px);
+ margin: 0 px2rem(12px) px2rem(24px);
+ }
+
+ // Post metadata
+ .md-post__meta {
+
+ // Navigation link
+ a {
+ transition: color 125ms;
+
+ // Navigation link on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ }
+ }
+ }
+
+ // Post navigation title @todo - generalize
+ &__title {
+ font-weight: 700;
+ color: var(--md-default-fg-color--light);
+ }
+
+ // Post excerpt
+ &--excerpt {
+ margin-bottom: px2rem(64px);
+
+ // Post excerpt header
+ .md-post__header {
+ display: flex;
+ gap: px2rem(12px);
+ align-items: center;
+ min-height: px2rem(32px);
+ }
+
+ // Post excerpt authors
+ .md-post__authors {
+ display: inline-flex;
+ flex-direction: row;
+ gap: px2rem(4px);
+ align-items: center;
+ min-height: px2rem(48px);
+ margin: 0;
+ }
+
+ // Post excerpt metadata
+ .md-post__meta .md-meta__list {
+ margin-inline-end: px2rem(8px);
+ }
+
+ // Post excerpt content
+ .md-post__content > :first-child {
+ --md-scroll-margin: #{px2rem(120px)};
+
+ margin-top: 0;
+ }
+ }
+
+ // Add margin to table of contents
+ > .md-nav--secondary {
+ margin: 1em 0;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Post author profile
+.md-profile {
+ display: flex;
+ gap: px2rem(12px);
+ align-items: center;
+ width: 100%;
+ font-size: px2rem(14px);
+ line-height: 1.4;
+
+ // Post author description
+ &__description {
+ flex-grow: 1;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Content area for post
+.md-content--post {
+ display: flex;
+
+ // [tablet -]: Switch to inverted column layout
+ @include break-to-device(tablet) {
+ flex-flow: column-reverse;
+ }
+
+ // Content wrapper
+ > .md-content__inner {
+ min-width: 0;
+
+ // [screen +]: Adjust spacing between content area and sidebars
+ @include break-from-device(screen) {
+ margin-inline-start: px2rem(24px);
+ }
+ }
+}
+
+// Sidebar for post
+.md-sidebar.md-sidebar--post {
+
+ // [tablet -]: Adjust spacing
+ @include break-to-device(tablet) {
+ position: initial;
+ width: 100%;
+ padding: 0;
+
+ .md-sidebar__inner {
+ padding: 0;
+ }
+
+ .md-post__meta {
+ margin-inline: px2rem(12px);
+ }
+
+ .md-nav__item {
+ display: inline;
+ border: none;
+ }
+
+ .md-nav__list {
+ display: inline-flex;
+ flex-wrap: wrap;
+ gap: px2rem(12px);
+ padding-block: px2rem(12px);
+ }
+
+ .md-nav__link {
+ padding: 0;
+ }
+
+ .md-nav {
+ position: initial;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_progress.scss b/src/templates/assets/stylesheets/main/components/_progress.scss
new file mode 100644
index 00000000..7386ae33
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_progress.scss
@@ -0,0 +1,53 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Progress variables
+:root {
+ --md-progress-value: 0;
+ --md-progress-delay: 400ms;
+}
+
+// ----------------------------------------------------------------------------
+
+// Progress indicator
+.md-progress {
+ position: fixed;
+ top: 0;
+ z-index: 4;
+ width: 100%;
+ height: px2rem(1.5px);
+ background: var(--md-primary-bg-color);
+ opacity:
+ min(
+ clamp(0, var(--md-progress-value), 1),
+ clamp(0, 100 - var(--md-progress-value), 1)
+ );
+ transition:
+ transform 500ms cubic-bezier(0.19, 1, 0.22, 1),
+ opacity 250ms var(--md-progress-delay);
+ transform: scaleX(calc(var(--md-progress-value) * 1%));
+ transform-origin: left;
+}
diff --git a/src/templates/assets/stylesheets/main/components/_search.scss b/src/templates/assets/stylesheets/main/components/_search.scss
new file mode 100644
index 00000000..e0f36b0c
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_search.scss
@@ -0,0 +1,707 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Search variables
+:root {
+ --md-search-result-icon: svg-load("material/file-search-outline.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Search
+.md-search {
+ position: relative;
+
+ // [tablet landscape +]: Header-embedded search
+ @include break-from-device(tablet landscape) {
+ padding: px2rem(4px) 0;
+ }
+
+ // [no-js]: Hide search
+ .no-js & {
+ display: none;
+ }
+
+ // Search overlay
+ &__overlay {
+ z-index: 1;
+ opacity: 0;
+
+ // [tablet portrait -]: Search modal
+ @include break-to-device(tablet portrait) {
+ position: absolute;
+ top: px2rem(-20px);
+ width: px2rem(40px);
+ height: px2rem(40px);
+ overflow: hidden;
+ pointer-events: none;
+ background-color: var(--md-default-bg-color);
+ border-radius: px2rem(20px);
+ transition:
+ transform 300ms 100ms,
+ opacity 200ms 200ms;
+ transform-origin: center;
+ inset-inline-start: px2rem(-44px);
+
+ // Show overlay when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ opacity: 1;
+ transition:
+ transform 400ms,
+ opacity 100ms;
+ }
+ }
+
+ // [tablet landscape +]: Header-embedded search
+ @include break-from-device(tablet landscape) {
+ position: fixed;
+ top: 0;
+ width: 0;
+ height: 0;
+ cursor: pointer;
+ background-color: hsla(0, 0%, 0%, 0.54);
+ transition:
+ width 0ms 250ms,
+ height 0ms 250ms,
+ opacity 250ms;
+ inset-inline-start: 0;
+
+ // Show overlay when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ width: 100%;
+ // Hack: when the header is translated upon scrolling, a new layer is
+ // induced, which means that the height will now refer to the height of
+ // the header, albeit positioning is fixed. This should be mitigated
+ // in all cases when setting the height to 2x the viewport.
+ height: 200vh;
+ opacity: 1;
+ transition:
+ width 0ms,
+ height 0ms,
+ opacity 250ms;
+ }
+ }
+
+ // Adjust appearance when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+
+ // [mobile portrait -]: Scale up 45 times
+ @include break-to-device(mobile portrait) {
+ transform: scale(45);
+ }
+
+ // [mobile landscape]: Scale up 60 times
+ @include break-at-device(mobile landscape) {
+ transform: scale(60);
+ }
+
+ // [tablet portrait]: Scale up 75 times
+ @include break-at-device(tablet portrait) {
+ transform: scale(75);
+ }
+ }
+ }
+
+ // Search wrapper
+ &__inner {
+ // Hack: promote to own layer to reduce jitter
+ backface-visibility: hidden;
+
+ // [tablet portrait -]: Search modal
+ @include break-to-device(tablet portrait) {
+ position: fixed;
+ top: 0;
+ z-index: 2;
+ width: 0;
+ height: 0;
+ overflow: hidden;
+ opacity: 0;
+ transition:
+ width 0ms 300ms,
+ height 0ms 300ms,
+ transform 150ms 150ms cubic-bezier(0.4, 0, 0.2, 1),
+ opacity 150ms 150ms;
+ transform: translateX(5%);
+ inset-inline-start: 0;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: translateX(-5%);
+ }
+
+ // Adjust appearance when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ width: 100%;
+ height: 100%;
+ opacity: 1;
+ transition:
+ width 0ms 0ms,
+ height 0ms 0ms,
+ transform 150ms 150ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ opacity 150ms 150ms;
+ transform: translateX(0);
+ }
+ }
+
+ // [tablet landscape +]: Header-embedded search
+ @include break-from-device(tablet landscape) {
+ position: relative;
+ float: inline-end;
+ width: px2rem(234px);
+ padding: px2rem(2px) 0;
+ transition: width 250ms cubic-bezier(0.1, 0.7, 0.1, 1);
+ }
+
+ // Adjust appearance when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+
+ // [tablet landscape]: Omit overlaying header title
+ @include break-at-device(tablet landscape) {
+ width: px2rem(468px);
+ }
+
+ // [screen +]: Match width of content area
+ @include break-from-device(screen) {
+ width: px2rem(688px);
+ }
+ }
+ }
+
+ // Search form
+ &__form {
+ position: relative;
+ z-index: 2;
+ height: px2rem(48px);
+ background-color: var(--md-default-bg-color);
+ box-shadow: 0 0 px2rem(12px) transparent;
+ transition:
+ color 250ms,
+ background-color 250ms;
+
+ // [tablet landscape +]: Header-embedded search
+ @include break-from-device(tablet landscape) {
+ height: px2rem(36px);
+ background-color: hsla(0, 0%, 0%, 0.26);
+ border-radius: px2rem(2px);
+
+ // Search form on hover
+ &:hover {
+ background-color: hsla(0, 0%, 100%, 0.12);
+ }
+ }
+
+ // Adjust appearance when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ color: var(--md-default-fg-color);
+ background-color: var(--md-default-bg-color);
+ border-radius: px2rem(2px) px2rem(2px) 0 0;
+ box-shadow: 0 0 px2rem(12px) hsla(0, 0%, 0%, 0.07);
+ }
+ }
+
+ // Search input
+ &__input {
+ position: relative;
+ z-index: 2;
+ width: 100%;
+ height: 100%;
+ padding-inline: px2rem(72px) px2rem(44px);
+ font-size: px2rem(18px);
+ text-overflow: ellipsis;
+ background: transparent;
+
+ // Search placeholder
+ &::placeholder {
+ transition: color 250ms;
+ }
+
+ // Search icon and placeholder
+ ~ .md-search__icon,
+ &::placeholder {
+ color: var(--md-default-fg-color--light);
+ }
+
+ // Remove the "x" rendered by Internet Explorer
+ &::-ms-clear {
+ display: none;
+ }
+
+ // [tablet portrait -]: Search modal
+ @include break-to-device(tablet portrait) {
+ width: 100%;
+ height: px2rem(48px);
+ font-size: px2rem(18px);
+ }
+
+ // [tablet landscape +]: Header-embedded search
+ @include break-from-device(tablet landscape) {
+ padding-inline-start: px2rem(44px);
+ font-size: px2rem(16px);
+ color: inherit;
+
+ // Search placeholder
+ &::placeholder {
+ color: var(--md-primary-bg-color--light);
+ }
+
+ // Search icon
+ + .md-search__icon {
+ color: var(--md-primary-bg-color);
+ }
+
+ // Adjust appearance when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ text-overflow: clip;
+
+ // Search icon and placeholder
+ + .md-search__icon {
+ color: var(--md-default-fg-color--light);
+ }
+
+ // Search placeholder
+ &::placeholder {
+ color: transparent;
+ }
+ }
+ }
+ }
+
+ // Search icon
+ &__icon {
+ display: inline-block;
+ width: px2rem(24px);
+ height: px2rem(24px);
+ cursor: pointer;
+ transition:
+ color 250ms,
+ opacity 250ms;
+
+ // Search icon on hover
+ &:hover {
+ opacity: 0.7;
+ }
+
+ // Search focus button
+ &[for="__search"] {
+ position: absolute;
+ top: px2rem(6px);
+ inset-inline-start: px2rem(10px);
+ z-index: 2;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & svg {
+ transform: scaleX(-1);
+ }
+
+ // [tablet portrait -]: Search modal
+ @include break-to-device(tablet portrait) {
+ top: px2rem(12px);
+ inset-inline-start: px2rem(16px);
+
+ // Hide the magnifying glass
+ svg:first-child {
+ display: none;
+ }
+ }
+
+ // [tablet landscape +]: Header-embedded search
+ @include break-from-device(tablet landscape) {
+ pointer-events: none;
+
+ // Hide the back arrow
+ svg:last-child {
+ display: none;
+ }
+ }
+ }
+ }
+
+ // Search options
+ &__options {
+ position: absolute;
+ top: px2rem(6px);
+ inset-inline-end: px2rem(10px);
+ z-index: 2;
+ pointer-events: none;
+
+ // [tablet portrait -]: Search modal
+ @include break-to-device(tablet portrait) {
+ top: px2rem(12px);
+ inset-inline-end: px2rem(16px);
+ }
+
+ // Search option buttons
+ > .md-icon {
+ margin-inline-start: px2rem(4px);
+ color: var(--md-default-fg-color--light);
+ opacity: 0;
+ transition:
+ transform 150ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ opacity 150ms;
+ transform: scale(0.75);
+
+ // Hide outline for pointer devices
+ &:not(.focus-visible) {
+ outline: none;
+ -webkit-tap-highlight-color: transparent;
+ }
+
+ // Show buttons when search is active and input non-empty
+ [data-md-toggle="search"]:checked ~ .md-header // stylelint-disable-line
+ .md-search__input:valid ~ & {
+ pointer-events: initial;
+ opacity: 1;
+ transform: scale(1);
+
+ // Search focus icon
+ &:hover {
+ opacity: 0.7;
+ }
+ }
+ }
+ }
+
+ // Search suggestions
+ &__suggest {
+ position: absolute;
+ top: 0;
+ display: flex;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+ padding-inline: px2rem(72px) px2rem(44px);
+ font-size: px2rem(18px);
+ color: var(--md-default-fg-color--lighter);
+ white-space: nowrap;
+ opacity: 0;
+ transition: opacity 50ms;
+
+ // [tablet landscape +]: Header-embedded search
+ @include break-from-device(tablet landscape) {
+ padding-inline-start: px2rem(44px);
+ font-size: px2rem(16px);
+ }
+
+ // Show suggestions when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ opacity: 1;
+ transition: opacity 300ms 100ms;
+ }
+ }
+
+ // Search output
+ &__output {
+ position: absolute;
+ z-index: 1;
+ width: 100%;
+ overflow: hidden;
+ border-end-start-radius: px2rem(2px);
+ border-end-end-radius: px2rem(2px);
+
+ // [tablet portrait -]: Search modal
+ @include break-to-device(tablet portrait) {
+ top: px2rem(48px);
+ bottom: 0;
+ }
+
+ // [tablet landscape +]: Header-embedded search
+ @include break-from-device(tablet landscape) {
+ top: px2rem(38px);
+ opacity: 0;
+ transition: opacity 400ms;
+
+ // Show output when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ box-shadow: var(--md-shadow-z3);
+ opacity: 1;
+ }
+ }
+ }
+
+ // Search scroll wrapper
+ &__scrollwrap {
+ height: 100%;
+ overflow-y: auto;
+ // Hack: Chrome 88+ has weird overscroll behavior. Overall, scroll snapping
+ // seems to be something that is not ready for prime time on some browsers.
+ // scroll-snap-type: y mandatory;
+ touch-action: pan-y;
+ background-color: var(--md-default-bg-color);
+ // Hack: promote to own layer to reduce jitter
+ backface-visibility: hidden;
+
+ // Mitigiate excessive repaints on non-retina devices
+ @media (max-resolution: 1dppx) {
+ transform: translateZ(0);
+ }
+
+ // [tablet landscape]: Set fixed width to omit unnecessary reflow
+ @include break-at-device(tablet landscape) {
+ width: px2rem(468px);
+ }
+
+ // [screen +]: Set fixed width to omit unnecessary reflow
+ @include break-from-device(screen) {
+ width: px2rem(688px);
+ }
+
+ // [tablet landscape +]: Limit height to viewport
+ @include break-from-device(tablet landscape) {
+ max-height: 0;
+ scrollbar-width: thin;
+ scrollbar-color: var(--md-default-fg-color--lighter) transparent;
+
+ // Show scroll wrapper when search is active
+ [data-md-toggle="search"]:checked ~ .md-header & {
+ max-height: 75vh;
+ }
+
+ // Search scroll wrapper on hover
+ &:hover {
+ scrollbar-color: var(--md-accent-fg-color) transparent;
+ }
+
+ // Webkit scrollbar
+ &::-webkit-scrollbar {
+ width: px2rem(4px);
+ height: px2rem(4px);
+ }
+
+ // Webkit scrollbar thumb
+ &::-webkit-scrollbar-thumb {
+ background-color: var(--md-default-fg-color--lighter);
+
+ // Webkit scrollbar thumb on hover
+ &:hover {
+ background-color: var(--md-accent-fg-color);
+ }
+ }
+ }
+ }
+}
+
+// Search result
+.md-search-result {
+ color: var(--md-default-fg-color);
+ word-break: break-word;
+
+ // Search result metadata
+ &__meta {
+ padding: 0 px2rem(16px);
+ font-size: px2rem(12.8px);
+ line-height: px2rem(36px);
+ color: var(--md-default-fg-color--light);
+ background-color: var(--md-default-fg-color--lightest);
+ scroll-snap-align: start;
+
+ // [tablet landscape +]: Adjust spacing
+ @include break-from-device(tablet landscape) {
+ padding-inline-start: px2rem(44px);
+ }
+ }
+
+ // Search result list
+ &__list {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ // Hack: omit accidental text selection on fast toggle of more button
+ user-select: none;
+ }
+
+ // Search result item
+ &__item {
+ box-shadow: 0 px2rem(-1px) var(--md-default-fg-color--lightest);
+
+ // Omit border on first child
+ &:first-child {
+ box-shadow: none;
+ }
+ }
+
+ // Search result link
+ &__link {
+ display: block;
+ outline: none;
+ transition: background-color 250ms;
+ scroll-snap-align: start;
+
+ // Search result link on focus/hover
+ &:is(:focus, :hover) {
+ background-color: var(--md-accent-fg-color--transparent);
+ }
+
+ // Adjust spacing on last child of last link
+ &:last-child p:last-child {
+ margin-bottom: px2rem(12px);
+ }
+ }
+
+ // Search result more container
+ &__more > summary {
+ position: sticky;
+ top: 0;
+ z-index: 1;
+ display: block;
+ cursor: pointer;
+ outline: none;
+ scroll-snap-align: start;
+
+ // Hide native details marker
+ &::marker {
+ display: none;
+ }
+
+ // Hide native details marker - legacy, must be split into a seprate rule,
+ // so older browsers don't consider the selector list as invalid
+ &::-webkit-details-marker {
+ display: none;
+ }
+
+ // Search result more button
+ > div {
+ padding: px2em(12px) px2rem(16px);
+ font-size: px2rem(12.8px);
+ color: var(--md-typeset-a-color);
+ transition:
+ color 250ms,
+ background-color 250ms;
+
+ // [tablet landscape +]: Adjust spacing
+ @include break-from-device(tablet landscape) {
+ padding-inline-start: px2rem(44px);
+ }
+ }
+
+ // Search result more link on focus/hover
+ &:is(:focus, :hover) > div {
+ color: var(--md-accent-fg-color);
+ background-color: var(--md-accent-fg-color--transparent);
+ }
+ }
+
+ // Adjust background for more container in open state
+ &__more[open] > summary {
+ background-color: var(--md-default-bg-color);
+ // box-shadow: 0 px2rem(-1px) hsla(0, 0%, 0%, 0.07) inset;
+ }
+
+ // Search result article
+ &__article {
+ position: relative;
+ padding: 0 px2rem(16px);
+ overflow: hidden;
+
+ // [tablet landscape +]: Adjust spacing
+ @include break-from-device(tablet landscape) {
+ padding-inline-start: px2rem(44px);
+ }
+ }
+
+ // Search result icon
+ &__icon {
+ position: absolute;
+ inset-inline-start: 0;
+ width: px2rem(24px);
+ height: px2rem(24px);
+ margin: px2rem(10px);
+ color: var(--md-default-fg-color--light);
+
+ // [tablet portrait -]: Hide icon
+ @include break-to-device(tablet portrait) {
+ display: none;
+ }
+
+ // Search result icon content
+ &::after {
+ display: inline-block;
+ width: 100%;
+ height: 100%;
+ content: "";
+ background-color: currentcolor;
+ mask-image: var(--md-search-result-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: scaleX(-1);
+ }
+ }
+ }
+
+ // Typesetted content
+ .md-typeset {
+ font-size: px2rem(12.8px);
+ line-height: 1.6;
+ color: var(--md-default-fg-color--light);
+
+ // Search result article title
+ h1 {
+ margin: px2rem(11px) 0;
+ font-size: px2rem(16px);
+ font-weight: 400;
+ line-height: 1.4;
+ color: var(--md-default-fg-color);
+
+ // Search term highlighting
+ mark {
+ text-decoration: none;
+ }
+ }
+
+ // Search result section title
+ h2 {
+ margin: 0.5em 0;
+ font-size: px2rem(12.8px);
+ font-weight: 700;
+ line-height: 1.6;
+ color: var(--md-default-fg-color);
+
+ // Search term highlighting
+ mark {
+ text-decoration: none;
+ }
+ }
+ }
+
+ // Search result terms
+ &__terms {
+ display: block;
+ margin: 0.5em 0;
+ font-size: px2rem(12.8px);
+ font-style: italic;
+ color: var(--md-default-fg-color);
+ }
+
+ // Search term highlighting
+ mark {
+ color: var(--md-accent-fg-color);
+ text-decoration: underline;
+ background-color: transparent;
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_select.scss b/src/templates/assets/stylesheets/main/components/_select.scss
new file mode 100644
index 00000000..ed597a39
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_select.scss
@@ -0,0 +1,115 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Selection
+.md-select {
+ position: relative;
+ z-index: 1;
+
+ // Selection tooltip
+ &__inner {
+ position: absolute;
+ top: calc(100% - #{px2rem(4px)});
+ left: 50%;
+ max-height: 0;
+ margin-top: px2rem(4px);
+ color: var(--md-default-fg-color);
+ background-color: var(--md-default-bg-color);
+ border-radius: px2rem(2px);
+ box-shadow: var(--md-shadow-z2);
+ opacity: 0;
+ transition:
+ transform 250ms 375ms,
+ opacity 250ms 250ms,
+ max-height 0ms 500ms;
+ transform: translate3d(-50%, px2rem(6px), 0);
+
+ // Selection bubble on parent focus/hover
+ .md-select:is(:focus-within, :hover) & {
+ max-height: px2rem(200px);
+ opacity: 1;
+ transition:
+ transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ opacity 250ms,
+ max-height 0ms;
+ transform: translate3d(-50%, 0, 0);
+ }
+
+ // Selection bubble handle
+ &::after {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ width: 0;
+ height: 0;
+ margin-top: px2rem(-4px);
+ margin-left: px2rem(-4px);
+ content: "";
+ border: px2rem(4px) solid transparent;
+ border-top: 0;
+ border-bottom-color: var(--md-default-bg-color);
+ }
+ }
+
+ // Selection list
+ &__list {
+ max-height: inherit;
+ padding: 0;
+ margin: 0;
+ overflow: auto;
+ font-size: px2rem(16px);
+ list-style-type: none;
+ border-radius: px2rem(2px);
+ }
+
+ // Selection item
+ &__item {
+ line-height: px2rem(36px);
+ }
+
+ // Selection link
+ &__link {
+ display: block;
+ width: 100%;
+ padding-inline: px2rem(12px) px2rem(24px);
+ cursor: pointer;
+ outline: none;
+ transition:
+ background-color 250ms,
+ color 250ms;
+ scroll-snap-align: start;
+
+ // Link on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ }
+
+ // Link on focus
+ &:focus {
+ background-color: var(--md-default-fg-color--lightest);
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_sidebar.scss b/src/templates/assets/stylesheets/main/components/_sidebar.scss
new file mode 100644
index 00000000..8a320c04
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_sidebar.scss
@@ -0,0 +1,209 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Sidebar
+.md-sidebar {
+ position: sticky;
+ top: px2rem(48px);
+ flex-shrink: 0;
+ align-self: flex-start;
+ width: px2rem(242px);
+ padding: px2rem(24px) 0;
+
+ // [print]: Hide sidebar
+ @media print {
+ display: none;
+ }
+
+ // Primary sidebar with navigation
+ &--primary {
+
+ // [tablet -]: Show navigation as drawer
+ @include break-to-device(tablet) {
+ position: fixed;
+ top: 0;
+ z-index: 5;
+ display: block;
+ width: px2rem(242px);
+ height: 100%;
+ background-color: var(--md-default-bg-color);
+ transition:
+ transform 250ms cubic-bezier(0.4, 0, 0.2, 1),
+ box-shadow 250ms;
+ transform: translateX(0);
+ inset-inline-start: px2rem(-242px);
+
+ // Show sidebar when drawer is active
+ [data-md-toggle="drawer"]:checked ~ .md-container & {
+ box-shadow: var(--md-shadow-z3);
+ transform: translateX(px2rem(242px));
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: translateX(px2rem(-242px));
+ }
+ }
+
+ // Stretch scroll wrapper for primary sidebar
+ .md-sidebar__scrollwrap {
+ position: absolute;
+ inset: 0;
+ margin: 0;
+ scroll-snap-type: none;
+ overflow: hidden;
+ }
+ }
+ }
+
+ // [screen +]: Show navigation as sidebar
+ @include break-from-device(screen) {
+ height: 0;
+
+ // [no-js]: Switch to native sticky behavior
+ .no-js & {
+ height: auto;
+ }
+
+ // Adjust spacing for sticky navigation tabs
+ .md-header--lifted ~ .md-container & {
+ top: px2rem(96px);
+ }
+ }
+
+ // Secondary sidebar with table of contents
+ &--secondary {
+ display: none;
+ order: 2;
+
+ // [tablet landscape +]: Show table of contents as sidebar
+ @include break-from-device(tablet landscape) {
+ height: 0;
+
+ // [no-js]: Switch to native sticky behavior
+ .no-js & {
+ height: auto;
+ }
+
+ // Sidebar is visible
+ &:not([hidden]) {
+ display: block;
+ }
+
+ // Ensure smooth scrolling on iOS
+ .md-sidebar__scrollwrap {
+ touch-action: pan-y;
+ }
+ }
+ }
+
+ // Sidebar scroll wrapper
+ &__scrollwrap {
+ margin: 0 px2rem(4px);
+ overflow-y: auto;
+ // Hack: promote to own layer to reduce jitter
+ backface-visibility: hidden;
+ // Hack: Chrome 81+ exhibits a strange bug, where it scrolls the container
+ // to the bottom if `scroll-snap-type` is set on the initial render. For
+ // this reason, we disable scroll snapping until this is resolved (#1667).
+ // scroll-snap-type: y mandatory;
+ scrollbar-width: thin;
+ scrollbar-gutter: stable;
+ scrollbar-color: var(--md-default-fg-color--lighter) transparent;
+
+ // Webkit scrollbar
+ &::-webkit-scrollbar {
+ width: px2rem(4px);
+ height: px2rem(4px);
+ }
+
+ // Sidebar scroll wrapper on focus/hover
+ &:is(:focus-within, :hover) {
+ scrollbar-color: var(--md-accent-fg-color) transparent;
+
+ // Webkit scrollbar thumb
+ &::-webkit-scrollbar-thumb {
+ background-color: var(--md-default-fg-color--lighter);
+
+ // Webkit scrollbar thumb on hover
+ &:hover {
+ background-color: var(--md-accent-fg-color);
+ }
+ }
+ }
+ }
+
+ // Hack: the scrollbar is only visible when the sidebar's contents overflow,
+ // which is nice, but leads to the problem where the chevrons of expandable
+ // sections will jump by `4px` when the sidebar is shown. We wanted to fix
+ // this problem for so long, but haven't found a clean way of doing it.
+ // Until now. The following declaration is only applied to Webkit browsers
+ // (e.g. Chrome and Safari), which support styling of scrollbars. The trick
+ // is to add conditional padding on the side of the scrollbar only if the
+ // sidebar's content doesn't overflow. This hack is inspired and adapted
+ // from Ayke van Laëthem's year old trick – see https://bit.ly/3Sb1qql
+ @supports selector(::-webkit-scrollbar) {
+
+ // Sidebar scroll wrapper
+ &__scrollwrap {
+ scrollbar-gutter: auto;
+ }
+
+ // Sidebar wrapper
+ &__inner {
+ padding-inline-end: calc(100% - #{px2rem(230px)});
+ }
+ }
+}
+
+// [tablet -]: Show overlay on active drawer
+@include break-to-device(tablet) {
+
+ // Drawer overlay
+ .md-overlay {
+ position: fixed;
+ top: 0;
+ z-index: 5;
+ width: 0;
+ height: 0;
+ background-color: hsla(0, 0%, 0%, 0.54);
+ opacity: 0;
+ transition:
+ width 0ms 250ms,
+ height 0ms 250ms,
+ opacity 250ms;
+
+ // Show overlay when drawer is active
+ [data-md-toggle="drawer"]:checked ~ & {
+ width: 100%;
+ height: 100%;
+ opacity: 1;
+ transition:
+ width 0ms,
+ height 0ms,
+ opacity 250ms;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_source.scss b/src/templates/assets/stylesheets/main/components/_source.scss
new file mode 100644
index 00000000..a2b72009
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_source.scss
@@ -0,0 +1,182 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Keyframes
+// ----------------------------------------------------------------------------
+
+// Show repository facts
+@keyframes facts {
+ 0% {
+ height: 0;
+ }
+
+ 100% {
+ height: px2rem(13px);
+ }
+}
+
+// Show repository fact
+@keyframes fact {
+ 0% {
+ opacity: 0;
+ transform: translateY(100%);
+ }
+
+ 50% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ transform: translateY(0%);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Repository information variables
+:root {
+ --md-source-forks-icon: svg-load("octicons/repo-forked-16.svg");
+ --md-source-repositories-icon: svg-load("octicons/repo-16.svg");
+ --md-source-stars-icon: svg-load("octicons/star-16.svg");
+ --md-source-version-icon: svg-load("octicons/tag-16.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Repository information
+.md-source {
+ display: block;
+ font-size: px2rem(13px);
+ line-height: 1.2;
+ white-space: nowrap;
+ outline-color: var(--md-accent-fg-color);
+ // Hack: promote to own layer to reduce jitter
+ backface-visibility: hidden;
+ transition: opacity 250ms;
+
+ // Repository information on hover
+ &:hover {
+ opacity: 0.7;
+ }
+
+ // Repository icon
+ &__icon {
+ display: inline-block;
+ width: px2rem(40px);
+ height: px2rem(48px);
+ vertical-align: middle;
+
+ // Align with margin only (as opposed to normal button alignment)
+ svg {
+ margin-inline-start: px2rem(12px);
+ margin-top: px2rem(12px);
+ }
+
+ // Adjust spacing if icon is present
+ + .md-source__repository {
+ padding-inline-start: px2rem(40px);
+ margin-inline-start: px2rem(-40px);
+ }
+ }
+
+ // Repository name
+ &__repository {
+ display: inline-block;
+ max-width: calc(100% - #{px2rem(24px)});
+ margin-inline-start: px2rem(12px);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ vertical-align: middle;
+ }
+
+ // Repository facts
+ &__facts {
+ display: flex;
+ gap: px2rem(8px);
+ width: 100%;
+ padding: 0;
+ margin: px2rem(2px) 0 0;
+ overflow: hidden;
+ font-size: px2rem(11px);
+ list-style-type: none;
+ opacity: 0.75;
+
+ // Show after the data was loaded
+ .md-source__repository--active & {
+ animation: facts 250ms ease-in;
+ }
+ }
+
+ // Repository fact
+ &__fact {
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ // Show after the data was loaded
+ .md-source__repository--active & {
+ animation: fact 400ms ease-out;
+ }
+
+ // Repository fact icon
+ &::before {
+ display: inline-block;
+ width: px2rem(12px);
+ height: px2rem(12px);
+ margin-inline-end: px2rem(2px);
+ vertical-align: text-top;
+ content: "";
+ background-color: currentcolor;
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+
+ // Adjust spacing for 2nd+ fact
+ &:nth-child(1n+2) {
+ flex-shrink: 0;
+ }
+
+ // Repository fact: version
+ &--version::before {
+ mask-image: var(--md-source-version-icon);
+ }
+
+ // Repository fact: stars
+ &--stars::before {
+ mask-image: var(--md-source-stars-icon);
+ }
+
+ // Repository fact: forks
+ &--forks::before {
+ mask-image: var(--md-source-forks-icon);
+ }
+
+ // Repository fact: repositories
+ &--repositories::before {
+ mask-image: var(--md-source-repositories-icon);
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_status.scss b/src/templates/assets/stylesheets/main/components/_status.scss
new file mode 100644
index 00000000..9e096021
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_status.scss
@@ -0,0 +1,73 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Status variables
+:root {
+ --md-status: svg-load("material/information-outline.svg");
+ --md-status--new: svg-load("material/alert-decagram.svg");
+ --md-status--deprecated: svg-load("material/trash-can.svg");
+ --md-status--encrypted: svg-load("material/shield-lock.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Status
+.md-status {
+
+ // Status icon
+ &::after {
+ display: inline-block;
+ width: px2em(18px);
+ height: px2em(18px);
+ vertical-align: text-bottom;
+ content: "";
+ background-color: var(--md-default-fg-color--light);
+ mask-image: var(--md-status);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+
+ // Status icon on hover
+ &:hover::after {
+ background-color: currentcolor;
+ }
+
+ // Status: new
+ &--new::after {
+ mask-image: var(--md-status--new);
+ }
+
+ // Status: deprecated
+ &--deprecated::after {
+ mask-image: var(--md-status--deprecated);
+ }
+
+ // Status: encrypted
+ &--encrypted::after {
+ mask-image: var(--md-status--encrypted);
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_tabs.scss b/src/templates/assets/stylesheets/main/components/_tabs.scss
new file mode 100644
index 00000000..0da3384b
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_tabs.scss
@@ -0,0 +1,133 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Navigation tabs
+.md-tabs {
+ // Must be higher than the z-index of the back-to-top button, or the button
+ // will overlay the navigation tabs bar when scrolling up fast.
+ z-index: 3;
+ display: block;
+ width: 100%;
+ overflow: auto;
+ line-height: 1.3;
+ color: var(--md-primary-bg-color);
+ background-color: var(--md-primary-fg-color);
+
+ // [print]: Hide tabs
+ @media print {
+ display: none;
+ }
+
+ // [tablet -]: Hide tabs
+ @include break-to-device(tablet) {
+ display: none;
+ }
+
+ // Navigation tabs are hidden
+ &[hidden] {
+ pointer-events: none;
+ }
+
+ // Navigation tabs list
+ &__list {
+ display: flex;
+ padding: 0;
+ margin: 0;
+ margin-inline-start: px2rem(4px);
+ overflow: auto;
+ white-space: nowrap;
+ list-style: none;
+ contain: content;
+ // Hack: don't show scrollbar when navigation tabs overflow, which should
+ // only happen in rare occasions, as adding too many top level sections is
+ // discouraged, since hiding content on horitontal axis doesn't lead to a
+ // good user experience. It's just harder to discover.
+ scrollbar-width: none;
+
+ // Hack: see above
+ &::-webkit-scrollbar {
+ display: none;
+ }
+ }
+
+ // Navigation tabs item
+ &__item {
+ height: px2rem(48px);
+ padding-inline: px2rem(12px);
+
+ // Navigation tabs link in active navigation
+ &--active .md-tabs__link {
+ color: inherit;
+ opacity: 1;
+ }
+ }
+
+ // Navigation tabs link - could be defined as block elements and aligned via
+ // line height, but this would imply more repaints when scrolling
+ &__link {
+ display: flex;
+ margin-top: px2rem(16px);
+ font-size: px2rem(14px);
+ outline-color: var(--md-accent-fg-color);
+ outline-offset: px2rem(4px);
+ // Hack: save a repaint when tabs are appearing on scrolling up
+ backface-visibility: hidden;
+ opacity: 0.7;
+ transition:
+ transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ opacity 250ms;
+
+ // Navigation tabs link on focus/hover
+ &:is(:focus, :hover) {
+ color: inherit;
+ opacity: 1;
+ }
+
+ // Navigation tabs link icon
+ svg {
+ height: 1.3em;
+ margin-inline-end: px2rem(8px);
+ fill: currentcolor;
+ }
+
+ // Delay transitions by a small amount
+ @for $i from 2 through 16 {
+ .md-tabs__item:nth-child(#{$i}) & {
+ transition-delay: 20ms * ($i - 1);
+ }
+ }
+
+ // Hide tabs upon scrolling - disable transition to minimizes repaints
+ // while scrolling down, while scrolling up seems to be okay
+ .md-tabs[hidden] & {
+ opacity: 0;
+ transition:
+ transform 0ms 100ms,
+ opacity 100ms;
+ transform: translateY(50%);
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_tag.scss b/src/templates/assets/stylesheets/main/components/_tag.scss
new file mode 100644
index 00000000..9f31829d
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_tag.scss
@@ -0,0 +1,105 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Tag variables
+:root {
+ --md-tag-icon: svg-load("material/pound.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Tag list
+ .md-tags {
+ display: inline-flex;
+ flex-wrap: wrap;
+ gap: px2em(8px);
+ margin-top: px2em(-2px);
+ margin-bottom: px2em(12px);
+ }
+
+ // Tag
+ .md-tag {
+ display: inline-flex;
+ gap: px2em(8px);
+ align-items: center;
+ padding: px2em(4px, 12.8px) px2em(10px, 12.8px);
+ font-size: px2rem(12.8px); // Fallback
+ font-size: min(px2em(12.8px), px2rem(12.8px));
+ font-weight: 700;
+ line-height: 1.6;
+ letter-spacing: initial;
+ background: var(--md-default-fg-color--lightest);
+ border-radius: px2rem(48px);
+
+ // Linked tag
+ &[href] {
+ color: inherit;
+ outline: none;
+ -webkit-tap-highlight-color: transparent;
+ transition:
+ color 125ms,
+ background-color 125ms;
+
+ // Linked tag on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-bg-color);
+ background-color: var(--md-accent-fg-color);
+ }
+ }
+
+ // Tag inside headline
+ [id] > & {
+ vertical-align: text-top;
+ }
+ }
+
+ // Tag icon
+ .md-tag-icon {
+
+ // Tag icon content
+ &::before {
+ display: inline-block;
+ width: 1.2em;
+ height: 1.2em;
+ vertical-align: text-bottom;
+ content: "";
+ background-color: var(--md-default-fg-color--lighter);
+ transition: background-color 125ms;
+ mask-image: var(--md-tag-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+
+ // Linked tag on focus/hover
+ &[href]:is(:focus, :hover)::before {
+ background-color: var(--md-accent-bg-color);
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_tooltip.scss b/src/templates/assets/stylesheets/main/components/_tooltip.scss
new file mode 100644
index 00000000..421e5858
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_tooltip.scss
@@ -0,0 +1,292 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Keyframes
+// ----------------------------------------------------------------------------
+
+// Continuous pulse animation
+@keyframes pulse {
+ 0% {
+ transform: scale(0.95);
+ }
+
+ 75% {
+ transform: scale(1);
+ }
+
+ 100% {
+ transform: scale(0.95);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Tooltip variables
+:root {
+ --md-annotation-bg-icon: svg-load("material/circle.svg");
+ --md-annotation-icon: svg-load("material/plus-circle.svg");
+ --md-tooltip-width: #{px2rem(400px)};
+}
+
+// ----------------------------------------------------------------------------
+
+// Tooltip
+.md-tooltip {
+ position: absolute;
+ top: var(--md-tooltip-y);
+ left:
+ clamp(
+ var(--md-tooltip-0, #{px2rem(0px)}) + #{px2rem(16px)},
+ var(--md-tooltip-x),
+ 100vw +
+ var(--md-tooltip-0, #{px2rem(0px)}) + #{px2rem(16px)} -
+ var(--md-tooltip-width) -
+ 2 * #{px2rem(16px)}
+ );
+ // Hack: set an explicit `z-index` so we can transition it to ensure that any
+ // following elements are not overlaying the tooltip during the transition.
+ z-index: 0;
+ width: var(--md-tooltip-width);
+ max-width: calc(100vw - 2 * #{px2rem(16px)});
+ font-family: var(--md-text-font-family);
+ color: var(--md-default-fg-color);
+ background-color: var(--md-default-bg-color);
+ border-radius: px2rem(2px);
+ box-shadow: var(--md-shadow-z2);
+ opacity: 0;
+ transition:
+ transform 0ms 250ms,
+ opacity 250ms,
+ z-index 250ms;
+ transform: translateY(px2rem(-8px));
+ // Hack: promote to own layer to reduce jitter
+ backface-visibility: hidden;
+
+ // Active tooltip
+ &--active {
+ z-index: 2;
+ opacity: 1;
+ transition:
+ transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1),
+ opacity 250ms,
+ z-index 0ms;
+ transform: translateY(0);
+ }
+
+ // Show outline on target and for keyboard devices
+ :is(.focus-visible > &, &:target) {
+ outline: var(--md-accent-fg-color) auto;
+ }
+
+ // Tooltip wrapper
+ &__inner {
+ padding: px2rem(16px);
+ font-size: px2rem(12.8px);
+
+ // Adjust spacing on first child
+ &.md-typeset > :first-child {
+ margin-top: 0;
+ }
+
+ // Adjust spacing on last child
+ &.md-typeset > :last-child {
+ margin-bottom: 0;
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Annotation
+.md-annotation {
+ font-weight: 400;
+ white-space: normal;
+ vertical-align: text-bottom;
+ outline: none;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ direction: rtl;
+ }
+
+ // Annotation index in code block
+ code & {
+ font-family: var(--md-code-font-family);
+ font-size: inherit;
+ }
+
+ // Annotation is not hidden (e.g. when copying)
+ &:not([hidden]) {
+ display: inline-block;
+ // Hack: ensure that the line height doesn't exceed the line height of the
+ // hosting line, because it will lead to dancing pixels.
+ line-height: 1.25;
+ }
+
+ // Annotation index
+ &__index {
+ position: relative;
+ z-index: 0;
+ display: inline-block;
+ margin-inline: 0.4ch;
+ vertical-align: text-top;
+ cursor: pointer;
+ user-select: none;
+ outline: none;
+
+ // Hack: increase specificity to override default for anchors in typesetted
+ // content, because transitions are defined on anchor elements
+ .md-annotation & {
+ transition: z-index 250ms;
+ }
+
+ // Hack: Work around Firefox bug that renders a subpixel outline when
+ // rotating a mask image element.
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1671784
+ overflow: hidden; // stylelint-disable-line order/properties-order
+ border-radius: 0.01px;
+
+ // [screen]: Render annotation markers as icons
+ @media screen {
+ width: 2.2ch;
+
+ // Annotation is visible
+ [data-md-visible] > & {
+ animation: pulse 2000ms infinite;
+ }
+
+ // Annotation marker background
+ &::before {
+ position: absolute;
+ top: -0.1ch;
+ z-index: -1;
+ width: 2.2ch;
+ height: 2.2ch;
+ content: "";
+ background: var(--md-default-bg-color);
+ mask-image: var(--md-annotation-bg-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+
+ // Annotation marker – the marker must be positioned absolutely behind
+ // the index, because it shouldn't impact the rendering of a code block.
+ // Otherwise, small rounding differences in browsers can sometimes mess up
+ // alignment of text following an annotation.
+ &::after {
+ position: absolute;
+ top: -0.1ch;
+ z-index: -1;
+ width: 2.2ch;
+ height: 2.2ch;
+ content: "";
+ background-color: var(--md-default-fg-color--lighter);
+ transition:
+ background-color 250ms,
+ transform 250ms;
+ // Hack: promote to own layer to reduce jitter
+ transform: scale(1.0001);
+ mask-image: var(--md-annotation-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+
+ // Annotation marker for active tooltip
+ .md-tooltip--active + & {
+ transform: rotate(45deg);
+ }
+
+ // Annotation marker for active tooltip or on hover
+ :is(.md-tooltip--active + &, :hover > &) {
+ background-color: var(--md-accent-fg-color);
+ }
+ }
+ }
+
+ // Annotation index for active tooltip
+ .md-tooltip--active + & {
+ z-index: 2;
+ transition-duration: 0ms;
+ animation-play-state: paused;
+ }
+
+ // Annotation marker
+ [data-md-annotation-id] {
+ display: inline-block;
+
+ // [print]: Render annotation markers as numbers
+ @media print {
+ padding: 0 0.6ch;
+ font-weight: 700;
+ color: var(--md-default-bg-color);
+ white-space: nowrap;
+ background: var(--md-default-fg-color--lighter);
+ border-radius: 2ch;
+
+ // Annotation marker content
+ &::after {
+ content: attr(data-md-annotation-id);
+ }
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Annotation list
+ .md-annotation-list {
+ list-style: none;
+ counter-reset: xxx;
+
+ // Annotation list item
+ li {
+ position: relative;
+
+ // Annotation list marker
+ &::before {
+ position: absolute;
+ top: px2em(4px);
+ inset-inline-start: px2em(-34px);
+ min-width: 2ch;
+ height: 2ch;
+ padding: 0 0.6ch;
+ font-size: px2em(14.2px);
+ font-weight: 700;
+ line-height: 1.25;
+ color: var(--md-default-bg-color);
+ text-align: center;
+ content: counter(xxx);
+ counter-increment: xxx;
+ background: var(--md-default-fg-color--lighter);
+ border-radius: 2ch;
+ }
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_top.scss b/src/templates/assets/stylesheets/main/components/_top.scss
new file mode 100644
index 00000000..c24d44d1
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_top.scss
@@ -0,0 +1,83 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Back-to-top button
+.md-top {
+ position: fixed;
+ top: px2rem(48px + 16px);
+ z-index: 2;
+ display: block;
+ padding: px2rem(8px) px2rem(16px);
+ margin-inline-start: 50%;
+ font-size: px2rem(14px);
+ color: var(--md-default-fg-color--light);
+ cursor: pointer;
+ background-color: var(--md-default-bg-color);
+ border-radius: px2rem(32px);
+ outline: none;
+ box-shadow: var(--md-shadow-z2);
+ transition:
+ color 125ms,
+ background-color 125ms,
+ transform 125ms cubic-bezier(0.4, 0, 0.2, 1),
+ opacity 125ms;
+ transform: translate(-50%, 0);
+
+ // [print]: Hide back-to-top button
+ @media print {
+ display: none;
+ }
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: translate(50%, 0);
+ }
+
+ // Back-to-top button is hidden
+ &[hidden] {
+ pointer-events: none;
+ opacity: 0;
+ transition-duration: 0ms;
+ transform: translate(-50%, px2rem(4px));
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: translate(50%, px2rem(4px));
+ }
+ }
+
+ // Back-to-top button on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-bg-color);
+ background-color: var(--md-accent-fg-color);
+ }
+
+ // Inline icon
+ svg {
+ display: inline-block;
+ vertical-align: -0.5em;
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/components/_version.scss b/src/templates/assets/stylesheets/main/components/_version.scss
new file mode 100644
index 00000000..3f85d6cd
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/components/_version.scss
@@ -0,0 +1,150 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Keyframes
+// ----------------------------------------------------------------------------
+
+// See https://github.com/squidfunk/mkdocs-material/issues/2429
+@keyframes hoverfix {
+ 0% {
+ pointer-events: none;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Version selection variables
+:root {
+ --md-version-icon: svg-load("fontawesome/solid/caret-down.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Version selection
+.md-version {
+ flex-shrink: 0;
+ height: px2rem(48px);
+ font-size: px2rem(16px);
+
+ // Current selection
+ &__current {
+ position: relative;
+ // Hack: in general, we would use `vertical-align` to align the version at
+ // the bottom with the title, but since the list uses absolute positioning,
+ // this won't work consistently. Furthermore, we would need to use inline
+ // positioning to align the links, which looks jagged.
+ top: px2rem(1px);
+ margin-inline: px2rem(28px) px2rem(8px);
+ color: inherit;
+ cursor: pointer;
+ outline: none;
+
+ // Version selection icon
+ &::after {
+ display: inline-block;
+ width: px2rem(8px);
+ height: px2rem(12px);
+ margin-inline-start: px2rem(8px);
+ content: "";
+ background-color: currentcolor;
+ mask-image: var(--md-version-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+ }
+
+ // Version selection list
+ &__list {
+ position: absolute;
+ top: px2rem(3px);
+ z-index: 3;
+ max-height: 0;
+ padding: 0;
+ margin: px2rem(4px) px2rem(16px);
+ overflow: auto;
+ color: var(--md-default-fg-color);
+ list-style-type: none;
+ background-color: var(--md-default-bg-color);
+ border-radius: px2rem(2px);
+ box-shadow: var(--md-shadow-z2);
+ opacity: 0;
+ transition:
+ max-height 0ms 500ms,
+ opacity 250ms 250ms;
+ scroll-snap-type: y mandatory;
+
+ // Version selection list on parent focus/hover
+ .md-version:is(:focus-within, :hover) & {
+ max-height: px2rem(200px);
+ opacity: 1;
+ transition:
+ max-height 0ms,
+ opacity 250ms;
+ }
+
+ // Fix hover on touch devices
+ @media (pointer: coarse), (hover: none) {
+ // Switch off on hover
+ .md-version:hover & {
+ animation: hoverfix 250ms forwards;
+ }
+
+ // Enable on focus
+ .md-version:focus-within & {
+ animation: none;
+ }
+ }
+ }
+
+ // Version selection item
+ &__item {
+ line-height: px2rem(36px);
+ }
+
+ // Version selection link
+ &__link {
+ display: block;
+ width: 100%;
+ padding-inline: px2rem(12px) px2rem(24px);
+ white-space: nowrap;
+ cursor: pointer;
+ outline: none;
+ transition:
+ color 250ms,
+ background-color 250ms;
+ scroll-snap-align: start;
+
+ // Link on focus/hover
+ &:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ }
+
+ // Link on focus
+ &:focus {
+ background-color: var(--md-default-fg-color--lightest);
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/markdown/_admonition.scss b/src/templates/assets/stylesheets/main/extensions/markdown/_admonition.scss
new file mode 100644
index 00000000..bf517989
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/markdown/_admonition.scss
@@ -0,0 +1,195 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+@use "sass:color";
+@use "sass:list";
+
+// ----------------------------------------------------------------------------
+// Variables
+// ----------------------------------------------------------------------------
+
+/// Admonition flavours
+$admonitions: (
+ "note": pencil-circle $clr-blue-a200,
+ "abstract": clipboard-text $clr-light-blue-a400,
+ "info": information $clr-cyan-a700,
+ "tip": fire $clr-teal-a700,
+ "success": check $clr-green-a700,
+ "question": help-circle $clr-light-green-a700,
+ "warning": alert $clr-orange-a400,
+ "failure": close $clr-red-a200,
+ "danger": lightning-bolt-circle $clr-red-a400,
+ "bug": shield-bug $clr-pink-a400,
+ "example": test-tube $clr-deep-purple-a200,
+ "quote": format-quote-close $clr-grey
+) !default;
+
+// ----------------------------------------------------------------------------
+// Rules: layout
+// ----------------------------------------------------------------------------
+
+// Admonition variables
+:root {
+ @each $name, $props in $admonitions {
+ --md-admonition-icon--#{$name}:
+ svg-load("material/#{list.nth($props, 1)}.svg");
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Admonition - note that all styles also apply to details tags, which are
+ // rendered as collapsible admonitions with summary elements as titles.
+ .admonition {
+ display: flow-root;
+ padding: 0 px2rem(12px);
+ margin: px2em(20px, 12.8px) 0;
+ font-size: px2rem(12.8px);
+ color: var(--md-admonition-fg-color);
+ background-color: var(--md-admonition-bg-color);
+ border: px2rem(1.5px) solid $clr-blue-a200;
+ border-radius: px2rem(4px);
+ box-shadow: var(--md-shadow-z1);
+ transition: box-shadow 125ms;
+ page-break-inside: avoid;
+
+ // [print]: Omit shadow as it may lead to rendering errors
+ @media print {
+ box-shadow: none;
+ }
+
+ // Admonition on focus
+ &:focus-within {
+ box-shadow: 0 0 0 px2rem(4px) color.adjust($clr-blue-a200, $alpha: -0.9);
+ }
+
+ // Hack: Chrome exhibits a weird issue where it will set nested elements to
+ // content-box. Doesn't happen in other browsers, so looks like a bug.
+ > * {
+ box-sizing: border-box;
+ }
+
+ // Adjust vertical spacing for nested admonitions
+ .admonition {
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+
+ // Adjust spacing for contained table wrappers
+ .md-typeset__scrollwrap {
+ margin: 1em px2rem(-12px);
+ }
+
+ // Adjust spacing for contained tables
+ .md-typeset__table {
+ padding: 0 px2rem(12px);
+ }
+
+ // Adjust spacing for single-child tabbed block container
+ > .tabbed-set:only-child {
+ margin-top: 0;
+ }
+
+ // Adjust spacing on last child
+ html & > :last-child {
+ margin-bottom: px2rem(12px);
+ }
+ }
+
+ // Admonition title
+ .admonition-title {
+ position: relative;
+ padding-block: px2rem(8px);
+ padding-inline: px2rem(40px) px2rem(12px);
+ margin-block: 0;
+ margin-inline: px2rem(-12px);
+ font-weight: 700;
+ background-color: color.adjust($clr-blue-a200, $alpha: -0.9);
+ border: none;
+ border-inline-start-width: px2rem(4px);
+ border-start-start-radius: px2rem(2px);
+ border-start-end-radius: px2rem(2px);
+
+ // Adjust spacing for title-only admonitions
+ html &:last-child {
+ margin-bottom: 0;
+ }
+
+ // Admonition icon
+ &::before {
+ position: absolute;
+ top: px2em(10px);
+ width: px2rem(20px);
+ height: px2rem(20px);
+ content: "";
+ background-color: $clr-blue-a200;
+ inset-inline-start: px2rem(12px);
+ mask-image: var(--md-admonition-icon--note);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+
+ // Inline code block
+ code {
+ box-shadow: 0 0 0 px2rem(1px) var(--md-default-fg-color--lightest);
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules: flavours
+// ----------------------------------------------------------------------------
+
+// Define admonition flavors
+@each $name, $props in $admonitions {
+ $tint: list.nth($props, 2);
+
+ // Admonition flavour
+ .md-typeset .admonition.#{$name} {
+ border-color: $tint;
+
+ // Admonition on focus
+ &:focus-within {
+ box-shadow: 0 0 0 px2rem(4px) color.adjust($tint, $alpha: -0.9);
+ }
+ }
+
+ // Admonition flavour title
+ .md-typeset .#{$name} > .admonition-title {
+ background-color: color.adjust($tint, $alpha: -0.9);
+
+ // Admonition icon
+ &::before {
+ background-color: $tint;
+ mask-image: var(--md-admonition-icon--#{$name});
+ }
+
+ // Details marker
+ &::after {
+ color: $tint;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/markdown/_footnotes.scss b/src/templates/assets/stylesheets/main/extensions/markdown/_footnotes.scss
new file mode 100644
index 00000000..59447d89
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/markdown/_footnotes.scss
@@ -0,0 +1,146 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Footnotes variables
+:root {
+ --md-footnotes-icon: svg-load("material/keyboard-return.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Footnote container
+ .footnote {
+ font-size: px2rem(12.8px);
+ color: var(--md-default-fg-color--light);
+
+ // Footnote list - omit left indentation
+ > ol {
+ margin-inline-start: 0;
+
+ // Footnote item - footnote items can contain lists, so we need to scope
+ // the spacing adjustments to the top-level footnote item.
+ > li {
+ transition: color 125ms;
+
+ // Darken color on target
+ &:target {
+ color: var(--md-default-fg-color);
+ }
+
+ // Show backreferences on footnote focus without transition
+ &:focus-within .footnote-backref {
+ opacity: 1;
+ transition: none;
+ transform: translateX(0);
+ }
+
+ // Show backreferences on footnote hover/target
+ &:is(:hover, :target) .footnote-backref {
+ opacity: 1;
+ transform: translateX(0);
+ }
+
+ // Adjust spacing on first child
+ > :first-child {
+ margin-top: 0;
+ }
+ }
+ }
+ }
+
+ // Footnote reference
+ .footnote-ref {
+ font-size: px2em(12px, 16px);
+ font-weight: 700;
+
+ // Hack: increase specificity to override default
+ html & {
+ outline-offset: px2rem(2px);
+ }
+ }
+
+ // Show outline for all devices
+ [id^="fnref:"]:target > .footnote-ref {
+ outline: auto;
+ }
+
+ // Footnote backreference
+ .footnote-backref {
+ display: inline-block;
+ // Hack: omit Unicode arrow for replacement with icon
+ font-size: 0;
+ color: var(--md-typeset-a-color);
+ vertical-align: text-bottom;
+ opacity: 0;
+ transition:
+ color 250ms,
+ transform 250ms 250ms,
+ opacity 125ms 250ms;
+ transform: translateX(px2rem(5px));
+
+ // [print]: Show footnote backreferences
+ @media print {
+ color: var(--md-typeset-a-color);
+ opacity: 1;
+ transform: translateX(0);
+ }
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: translateX(px2rem(-5px));
+ }
+
+ // Adjust color on hover
+ &:hover {
+ color: var(--md-accent-fg-color);
+ }
+
+ // Footnote backreference icon
+ &::before {
+ display: inline-block;
+ width: px2rem(16px);
+ height: px2rem(16px);
+ content: "";
+ background-color: currentcolor;
+ mask-image: var(--md-footnotes-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+
+ // Flip icon vertically
+ svg {
+ transform: scaleX(-1);
+ }
+ }
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/markdown/_toc.scss b/src/templates/assets/stylesheets/main/extensions/markdown/_toc.scss
new file mode 100644
index 00000000..8284a5c0
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/markdown/_toc.scss
@@ -0,0 +1,92 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Headerlink
+ .headerlink {
+ display: inline-block;
+ margin-inline-start: px2rem(10px);
+ color: var(--md-default-fg-color--lighter);
+ opacity: 0;
+ transition:
+ color 250ms,
+ opacity 125ms;
+
+ // [print]: Hide headerlinks
+ @media print {
+ display: none;
+ }
+ }
+
+ // Show headerlinks on parent hover
+ :is(:hover, :target) > .headerlink,
+ .headerlink:focus {
+ opacity: 1;
+ transition:
+ color 250ms,
+ opacity 125ms;
+ }
+
+ // Adjust color on parent target or focus/hover
+ :target > .headerlink,
+ .headerlink:is(:focus, :hover) {
+ color: var(--md-accent-fg-color);
+ }
+
+ // Adjust scroll margin for all elements with `id` attributes
+ :target {
+ --md-scroll-margin: #{px2rem(48px + 24px)};
+ --md-scroll-offset: #{px2rem(0px)};
+ // Scroll margin is finally ready for prime time - before, we used a hack
+ // for anchor correction based on pseudo elements but those times are gone.
+ scroll-margin-top:
+ calc(
+ var(--md-scroll-margin) -
+ var(--md-scroll-offset)
+ );
+
+ // [screen +]: Sticky navigation tabs
+ @include break-from-device(screen) {
+
+ // Adjust scroll margin for sticky navigation tabs
+ .md-header--lifted ~ .md-container & {
+ --md-scroll-margin: #{px2rem(96px + 24px)};
+ }
+ }
+ }
+
+ // Adjust scroll offset for headlines of level 1-3
+ :is(h1, h2, h3):target {
+ --md-scroll-offset: #{px2rem(4px)};
+ }
+
+ // Adjust scroll offset for headlines of level 4
+ h4:target {
+ --md-scroll-offset: #{px2rem(3px)};
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss b/src/templates/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss
new file mode 100644
index 00000000..fe8ffd62
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss
@@ -0,0 +1,52 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Arithmatex container
+ div.arithmatex {
+ overflow: auto;
+
+ // [mobile -]: Align with body copy
+ @include break-to-device(mobile) {
+ margin: 0 px2rem(-16px);
+ }
+
+ // Arithmatex content
+ > * {
+ width: min-content;
+ padding: 0 px2rem(16px);
+ margin-inline: auto !important; // stylelint-disable-line
+ touch-action: auto;
+
+ // MathJax container - see https://bit.ly/3HR8YJ5
+ mjx-container {
+ margin: 0 !important; // stylelint-disable-line
+ }
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/pymdownx/_critic.scss b/src/templates/assets/stylesheets/main/extensions/pymdownx/_critic.scss
new file mode 100644
index 00000000..683705ce
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/pymdownx/_critic.scss
@@ -0,0 +1,76 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Deletion
+ del.critic {
+ background-color: var(--md-typeset-del-color);
+ box-decoration-break: clone;
+ }
+
+ // Addition
+ ins.critic {
+ background-color: var(--md-typeset-ins-color);
+ box-decoration-break: clone;
+ }
+
+ // Comment
+ .critic.comment {
+ color: var(--md-code-hl-comment-color);
+ box-decoration-break: clone;
+
+ // Comment opening mark
+ &::before {
+ content: "/* ";
+ }
+
+ // Comment closing mark
+ &::after {
+ content: " */";
+ }
+ }
+
+ // Critic block
+ .critic.block {
+ display: block;
+ padding-inline: px2rem(16px);
+ margin: 1em 0;
+ overflow: auto;
+ box-shadow: none;
+
+ // Adjust spacing on first child
+ > :first-child {
+ margin-top: 0.5em;
+ }
+
+ // Adjust spacing on last child
+ > :last-child {
+ margin-bottom: 0.5em;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/pymdownx/_details.scss b/src/templates/assets/stylesheets/main/extensions/pymdownx/_details.scss
new file mode 100644
index 00000000..8eea678a
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/pymdownx/_details.scss
@@ -0,0 +1,121 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Details variables
+:root {
+ --md-details-icon: svg-load("material/chevron-right.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Details
+ details {
+ @extend .admonition;
+
+ display: flow-root;
+ padding-top: 0;
+ overflow: visible;
+
+ // Details title icon - rotate icon on transition to open state
+ &[open] > summary::after {
+ transform: rotate(90deg);
+ }
+
+ // Adjust spacing for details in closed state
+ &:not([open]) {
+ padding-bottom: 0;
+ box-shadow: none;
+
+ // Hack: we cannot set `overflow: hidden` on the `details` element (which
+ // is why we set it to `overflow: visible`, as the outline would not be
+ // visible when focusing. Therefore, we must set the border radius on the
+ // summary explicitly.
+ > summary {
+ border-radius: px2rem(2px);
+ }
+ }
+ }
+
+ // Details title
+ summary {
+ @extend .admonition-title;
+
+ display: block;
+ min-height: px2rem(20px);
+ padding-inline-end: px2rem(36px);
+ cursor: pointer;
+ border-start-start-radius: px2rem(2px);
+ border-start-end-radius: px2rem(2px);
+
+ // Show outline for keyboard devices
+ &.focus-visible {
+ outline-color: var(--md-accent-fg-color);
+ outline-offset: px2rem(4px);
+ }
+
+ // Hide outline for pointer devices
+ &:not(.focus-visible) {
+ outline: none;
+ -webkit-tap-highlight-color: transparent;
+ }
+
+ // Details marker
+ &::after {
+ position: absolute;
+ top: px2em(10px);
+ width: px2rem(20px);
+ height: px2rem(20px);
+ content: "";
+ background-color: currentcolor;
+ transition: transform 250ms;
+ transform: rotate(0deg);
+ inset-inline-end: px2rem(8px);
+ mask-image: var(--md-details-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: rotate(180deg);
+ }
+ }
+
+ // Hide native details marker - modern
+ &::marker {
+ display: none;
+ }
+
+ // Hide native details marker - legacy, must be split into a seprate rule,
+ // so older browsers don't consider the selector list as invalid
+ &::-webkit-details-marker {
+ display: none;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/pymdownx/_emoji.scss b/src/templates/assets/stylesheets/main/extensions/pymdownx/_emoji.scss
new file mode 100644
index 00000000..8b351013
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/pymdownx/_emoji.scss
@@ -0,0 +1,43 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Emoji and icon container
+ :is(.emojione, .twemoji, .gemoji) {
+ display: inline-flex;
+ height: px2em(18px);
+ vertical-align: text-top;
+
+ // Icon - inlined via mkdocs-material-extensions
+ svg {
+ width: px2em(18px);
+ max-height: 100%;
+ fill: currentcolor;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/pymdownx/_highlight.scss b/src/templates/assets/stylesheets/main/extensions/pymdownx/_highlight.scss
new file mode 100644
index 00000000..7d297677
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/pymdownx/_highlight.scss
@@ -0,0 +1,382 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules: syntax highlighting
+// ----------------------------------------------------------------------------
+
+// Code block
+.highlight {
+
+ // .o = Operator
+ // .ow = Operator, word
+ :is(.o, .ow) {
+ color: var(--md-code-hl-operator-color);
+ }
+
+ .p { // Punctuation
+ color: var(--md-code-hl-punctuation-color);
+ }
+
+ // .cpf = Comment, preprocessor file
+ // .l = Literal
+ // .s = Literal, string
+ // .sb = Literal, string backticks
+ // .sc = Literal, string char
+ // .s2 = Literal, string double
+ // .si = Literal, string interpol
+ // .s1 = Literal, string single
+ // .ss = Literal, string symbol
+ :is(.cpf, .l, .s, .sb, .sc, .s2, .si, .s1, .ss) {
+ color: var(--md-code-hl-string-color);
+ }
+
+ // .cp = Comment, pre-processor
+ // .se = Literal, string escape
+ // .sh = Literal, string heredoc
+ // .sr = Literal, string regex
+ // .sx = Literal, string other
+ :is(.cp, .se, .sh, .sr, .sx) {
+ color: var(--md-code-hl-special-color);
+ }
+
+ // .m = Number
+ // .mb = Number, binary
+ // .mf = Number, float
+ // .mh = Number, hex
+ // .mi = Number, integer
+ // .il = Number, integer long
+ // .mo = Number, octal
+ :is(.m, .mb, .mf, .mh, .mi, .il, .mo) {
+ color: var(--md-code-hl-number-color);
+ }
+
+ // .k = Keyword,
+ // .kd = Keyword, declaration
+ // .kn = Keyword, namespace
+ // .kp = Keyword, pseudo
+ // .kr = Keyword, reserved
+ // .kt = Keyword, type
+ :is(.k, .kd, .kn, .kp, .kr, .kt) {
+ color: var(--md-code-hl-keyword-color);
+ }
+
+ // .kc = Keyword, constant
+ // .n = Name
+ :is(.kc, .n) {
+ color: var(--md-code-hl-name-color);
+ }
+
+ // .no = Name, constant
+ // .nb = Name, builtin
+ // .bp = Name, builtin pseudo
+ :is(.no, .nb, .bp) {
+ color: var(--md-code-hl-constant-color);
+ }
+
+ // .nc = Name, class
+ // .ne = Name, exception
+ // .nf = Name, function
+ // .nn = Name, namespace
+ :is(.nc, .ne, .nf, .nn) {
+ color: var(--md-code-hl-function-color);
+ }
+
+ // .nd = Name, decorator
+ // .ni = Name, entity
+ // .nl = Name, label
+ // .nt = Name, tag
+ :is(.nd, .ni, .nl, .nt) {
+ color: var(--md-code-hl-keyword-color);
+ }
+
+ // .c = Comment
+ // .cm = Comment, multiline
+ // .c1 = Comment, single
+ // .ch = Comment, shebang
+ // .cs = Comment, special
+ // .sd = Literal, string doc
+ :is(.c, .cm, .c1, .ch, .cs, .sd) {
+ color: var(--md-code-hl-comment-color);
+ }
+
+ // .na = Name, attribute
+ // .nv = Variable,
+ // .vc = Variable, class
+ // .vg = Variable, global
+ // .vi = Variable, instance
+ :is(.na, .nv, .vc, .vg, .vi) {
+ color: var(--md-code-hl-variable-color);
+ }
+
+ // .ge = Generic, emph
+ // .gr = Generic, error
+ // .gh = Generic, heading
+ // .go = Generic, output
+ // .gp = Generic, prompt
+ // .gs = Generic, strong
+ // .gu = Generic, subheading
+ // .gt = Generic, traceback
+ :is(.ge, .gr, .gh, .go, .gp, .gs, .gu, .gt) {
+ color: var(--md-code-hl-generic-color);
+ }
+
+ // .gd = Diff, delete
+ // .gi = Diff, insert
+ :is(.gd, .gi) {
+ padding: 0 px2em(2px);
+ margin: 0 px2em(-2px);
+ border-radius: px2rem(2px);
+ }
+
+ .gd { // Diff, delete
+ background-color: var(--md-typeset-del-color);
+ }
+
+ .gi { // Diff, insert
+ background-color: var(--md-typeset-ins-color);
+ }
+
+ // Highlighted line
+ .hll {
+ display: block;
+ padding: 0 px2em(16px, 13.6px);
+ margin: 0 px2em(-16px, 13.6px);
+ background-color: var(--md-code-hl-color--light);
+ box-shadow: 2px 0 0 0 var(--md-code-hl-color) inset;
+ }
+
+ // Code block title
+ span.filename {
+ position: relative;
+ display: flow-root;
+ padding: px2em(9px, 13.6px) px2em(16px, 13.6px);
+ margin-top: 1em;
+ font-size: px2em(13.6px);
+ font-weight: 700;
+ background-color: var(--md-code-bg-color);
+ border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest);
+ border-top-left-radius: px2rem(2px);
+ border-top-right-radius: px2rem(2px);
+
+ // Adjust spacing for code block
+ + pre {
+ margin-top: 0;
+
+ // Remove rounded border on top side
+ > code {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+ }
+ }
+
+ // Code block line numbers (pymdownx-inline)
+ [data-linenos]::before {
+ position: sticky;
+ left: px2em(-16px, 13.6px);
+ // A `z-index` of 3 is necessary for ensuring that code block annotations
+ // don't overlay line numbers, as active annotations have a `z-index` of 2.
+ z-index: 3;
+ float: left;
+ padding-left: px2em(16px, 13.6px);
+ margin-right: px2em(16px, 13.6px);
+ margin-left: px2em(-16px, 13.6px);
+ color: var(--md-default-fg-color--light);
+ content: attr(data-linenos);
+ user-select: none;
+ background-color: var(--md-code-bg-color);
+ box-shadow: px2rem(-1px) 0 var(--md-default-fg-color--lightest) inset;
+ }
+
+ // Code block line anchors - Chrome and Safari seem to have a strange bug
+ // where scroll margin is not applied to anchors inside code blocks. Setting
+ // positioning to absolute seems to fix the problem. Interestingly, this does
+ // not happen in Firefox. Furthermore we must set `visibility: hidden` or
+ // the copy to clipboard functionality will include an empty line between
+ // each set of lines.
+ code a[id] {
+ position: absolute;
+ visibility: hidden;
+ }
+
+ // Copying in progress - this class is set before the content is copied and
+ // removed after copying is done to mitigate whitespace-related issues.
+ code[data-md-copying] {
+
+ // Temporarily remove highlighted lines - see https://bit.ly/32iVGWh
+ .hll {
+ display: contents;
+ }
+
+ // Temporarily remove annotations
+ .md-annotation {
+ display: none;
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules: layout
+// ----------------------------------------------------------------------------
+
+// Code block with line numbers
+.highlighttable {
+ display: flow-root;
+
+ // Set table elements to block layout, because otherwise the whole flexbox
+ // hacking won't work correctly
+ :is(tbody, td) {
+ display: block;
+ padding: 0;
+ }
+
+ // We need to use flexbox layout, because otherwise it's not possible to
+ // make the code container scroll while keeping the line numbers static
+ tr {
+ display: flex;
+ }
+
+ // The pre tags are nested inside a table, so we need to omit the margin
+ // because it collapses below all the overflows
+ pre {
+ margin: 0;
+ }
+
+ // Code block title container
+ th.filename {
+ flex-grow: 1;
+ padding: 0;
+ text-align: left;
+
+ // Adjust spacing
+ span.filename {
+ margin-top: 0;
+ }
+ }
+
+ // Code block line numbers - disable user selection, so code can be easily
+ // copied without accidentally also copying the line numbers
+ .linenos {
+ padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px);
+ padding-right: 0;
+ font-size: px2em(13.6px);
+ user-select: none;
+ background-color: var(--md-code-bg-color);
+ border-top-left-radius: px2rem(2px);
+ border-bottom-left-radius: px2rem(2px);
+ }
+
+ // Code block line numbers container
+ .linenodiv {
+ padding-right: px2em(8px, 13.6px);
+ box-shadow: px2rem(-1px) 0 var(--md-default-fg-color--lightest) inset;
+
+ // Adjust colors and alignment
+ pre {
+ color: var(--md-default-fg-color--light);
+ text-align: right;
+ }
+ }
+
+ // Code block container - stretch to remaining space
+ .code {
+ flex: 1;
+ min-width: 0;
+ }
+}
+
+// Code block line numbers container
+.linenodiv a {
+ color: inherit;
+}
+
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Code block with line numbers - unfortunately, these selectors need to be
+ // overly specific so they don't bleed into code blocks in annotations.
+ .highlighttable {
+ margin: 1em 0;
+ direction: ltr;
+
+ // Remove rounded borders on code blocks
+ > tbody > tr > .code > div > pre > code {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+ }
+
+ // Code block result container
+ .highlight + .result {
+ padding: 0 px2em(16px);
+ margin-top: calc(-1em + #{px2em(-2px)});
+ overflow: visible;
+ border: px2rem(1px) solid var(--md-code-bg-color);
+ border-top-width: px2rem(2px);
+ border-bottom-right-radius: px2rem(2px);
+ border-bottom-left-radius: px2rem(2px);
+
+ // Clearfix, because we can't use overflow: auto
+ &::after {
+ display: block;
+ clear: both;
+ content: "";
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules: top-level
+// ----------------------------------------------------------------------------
+
+// [mobile -]: Align with body copy
+@include break-to-device(mobile) {
+
+ // Top-level code block
+ .md-content__inner > .highlight {
+ margin: 1em px2rem(-16px);
+
+ // Remove rounded borders
+ > .filename,
+ > pre > code {
+ border-radius: 0;
+ }
+
+ // Code block with line numbers - unfortunately, these selectors need to be
+ // overly specific so they don't bleed into code blocks in annotations.
+ > .highlighttable > tbody > tr > .filename span.filename,
+ > .highlighttable > tbody > tr > .linenos,
+ > .highlighttable > tbody > tr > .code > div > pre > code {
+ border-radius: 0;
+ }
+
+ // Code block result container
+ + .result {
+ margin-inline: px2rem(-16px);
+ border-inline-width: 0;
+ border-radius: 0;
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/pymdownx/_keys.scss b/src/templates/assets/stylesheets/main/extensions/pymdownx/_keys.scss
new file mode 100644
index 00000000..8749f08c
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/pymdownx/_keys.scss
@@ -0,0 +1,115 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Keyboard key
+ .keys {
+
+ // Keyboard key icon
+ kbd:is(::before, ::after) {
+ position: relative;
+ margin: 0;
+ color: inherit;
+ -moz-osx-font-smoothing: initial;
+ -webkit-font-smoothing: initial;
+ }
+
+ // Surrounding text
+ span {
+ padding: 0 px2em(3.2px);
+ color: var(--md-default-fg-color--light);
+ }
+
+ // Define keyboard keys with left icon
+ @each $name, $code in (
+
+ // Modifiers
+ "alt": "\2387",
+ "left-alt": "\2387",
+ "right-alt": "\2387",
+ "command": "\2318",
+ "left-command": "\2318",
+ "right-command": "\2318",
+ "control": "\2303",
+ "left-control": "\2303",
+ "right-control": "\2303",
+ "meta": "\25C6",
+ "left-meta": "\25C6",
+ "right-meta": "\25C6",
+ "option": "\2325",
+ "left-option": "\2325",
+ "right-option": "\2325",
+ "shift": "\21E7",
+ "left-shift": "\21E7",
+ "right-shift": "\21E7",
+ "super": "\2756",
+ "left-super": "\2756",
+ "right-super": "\2756",
+ "windows": "\229E",
+ "left-windows": "\229E",
+ "right-windows": "\229E",
+
+ // Other keys
+ "arrow-down": "\2193",
+ "arrow-left": "\2190",
+ "arrow-right": "\2192",
+ "arrow-up": "\2191",
+ "backspace": "\232B",
+ "backtab": "\21E4",
+ "caps-lock": "\21EA",
+ "clear": "\2327",
+ "context-menu": "\2630",
+ "delete": "\2326",
+ "eject": "\23CF",
+ "end": "\2913",
+ "escape": "\238B",
+ "home": "\2912",
+ "insert": "\2380",
+ "page-down": "\21DF",
+ "page-up": "\21DE",
+ "print-screen": "\2399"
+ ) {
+ .key-#{$name}::before {
+ padding-right: px2em(6.4px);
+ content: $code;
+ }
+ }
+
+ // Define keyboard keys with right icon
+ @each $name, $code in (
+ "tab": "\21E5",
+ "num-enter": "\2324",
+ "enter": "\23CE"
+ ) {
+ .key-#{$name}::after {
+ padding-left: px2em(6.4px);
+ content: $code;
+ }
+ }
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss b/src/templates/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss
new file mode 100644
index 00000000..9df91bfc
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss
@@ -0,0 +1,400 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Tabbed variables
+:root {
+ --md-tabbed-icon--prev: svg-load("material/chevron-left.svg");
+ --md-tabbed-icon--next: svg-load("material/chevron-right.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Tabbed container
+ .tabbed-set {
+ position: relative;
+ display: flex;
+ flex-flow: column wrap;
+ margin: 1em 0;
+ border-radius: px2rem(2px);
+
+ // Tab radio button - the Tabbed extension will generate radio buttons with
+ // labels, so tabs can be triggered without the necessity for JavaScript.
+ // This is pretty cool, as it has great accessibility out-of-the box, so
+ // we just hide the radio button and toggle the label color for indication.
+ > input {
+ position: absolute;
+ width: 0;
+ height: 0;
+ opacity: 0;
+
+ // Adjust scroll margin
+ &:target {
+ --md-scroll-offset: #{px2em(10px, 16px)};
+ }
+
+ // Tab label states
+ @for $i from 20 through 1 {
+ &:nth-child(#{$i}) {
+
+ // Tab is active
+ &:checked {
+
+ // Tab label
+ ~ .tabbed-labels > :nth-child(#{$i}) {
+ @extend %tabbed-label;
+ }
+
+ // Tab content
+ ~ .tabbed-content > :nth-child(#{$i}) {
+ @extend %tabbed-content;
+ }
+ }
+
+ // Tab label on keyboard focus
+ &.focus-visible ~ .tabbed-labels > :nth-child(#{$i}) {
+ @extend %tabbed-label-focus-visible;
+ }
+ }
+ }
+
+ // Tab indicator on keyboard focus
+ &.focus-visible ~ .tabbed-labels::before {
+ background-color: var(--md-accent-fg-color);
+ }
+ }
+ }
+
+ // Tabbed labels
+ .tabbed-labels {
+ display: flex;
+ max-width: 100%;
+ overflow: auto;
+ box-shadow: 0 px2rem(-1px) var(--md-default-fg-color--lightest) inset;
+ -ms-overflow-style: none; // IE, Edge
+ scrollbar-width: none; // Firefox
+
+ // [print]: Move one layer up for ordering
+ @media print {
+ display: contents;
+ }
+
+ // [screen and no reduced motion]: Disable animation
+ @media screen {
+
+ // [js]: Show animated tab indicator
+ .js & {
+ position: relative;
+
+ // Tab indicator
+ &::before {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ display: block;
+ width: var(--md-indicator-width);
+ height: 2px;
+ content: "";
+ background: var(--md-default-fg-color);
+ transition:
+ width 225ms,
+ background-color 250ms,
+ transform 250ms;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transform: translateX(var(--md-indicator-x));
+ }
+ }
+ }
+
+ // Webkit scrollbar
+ &::-webkit-scrollbar {
+ display: none; // Chrome, Safari
+ }
+
+ // Tab label
+ > label {
+ flex-shrink: 0;
+ width: auto;
+ padding: px2em(10px, 12.8px) 1.25em px2em(8px, 12.8px);
+ font-size: px2rem(12.8px);
+ font-weight: 700;
+ color: var(--md-default-fg-color--light);
+ white-space: nowrap;
+ cursor: pointer;
+ border-bottom: px2rem(2px) solid transparent;
+ border-radius: px2rem(2px) px2rem(2px) 0 0;
+ transition:
+ background-color 250ms,
+ color 250ms;
+ scroll-margin-inline-start: px2rem(20px);
+
+ // [print]: Intersperse labels with containers
+ @media print {
+
+ // Ensure correct order of labels
+ @for $i from 1 through 20 {
+ &:nth-child(#{$i}) {
+ order: $i;
+ }
+ }
+ }
+
+ // Tab label on hover
+ &:hover {
+ color: var(--md-default-fg-color);
+ }
+ }
+ }
+
+ // Tabbed content
+ .tabbed-content {
+ width: 100%;
+
+ // [print]: Move one layer up for ordering
+ @media print {
+ display: contents;
+ }
+ }
+
+ // Tabbed block
+ .tabbed-block {
+ display: none;
+
+ // [print]: Intersperse labels with containers
+ @media print {
+ display: block;
+
+ // Ensure correct order of containers
+ @for $i from 1 through 20 {
+ &:nth-child(#{$i}) {
+ order: $i;
+ }
+ }
+ }
+
+ // Code block is the first child of a tab - remove margin and mirror
+ // previous (now deprecated) SuperFences code block grouping behavior
+ > pre:first-child,
+ > .highlight:first-child > pre {
+ margin: 0;
+
+ // Remove rounded borders on code block
+ > code {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+ }
+
+ // Code block is the first child of a tab - remove margin and mirror
+ // previous (now deprecated) SuperFences code block grouping behavior
+ > .highlight:first-child {
+
+ // Code block title - remove spacing and rounded borders
+ > .filename {
+ margin: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+
+ // Code block with line numbers - unfortunately, these selectors need to
+ // be overly specific so they don't bleed into code blocks in annotations.
+ > .highlighttable {
+ margin: 0;
+
+ // Remove rounded borders on line numbers and titles
+ > tbody > tr > .filename span.filename,
+ > tbody > tr > .linenos {
+ margin: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+
+ // Remove rounded borders on code blocks
+ > tbody > tr > .code > div > pre > code {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+ }
+
+ // Code block result container - adjust spacing
+ + .result {
+ margin-top: px2em(-2px);
+ }
+ }
+
+ // Adjust spacing for nested tabbed container
+ > .tabbed-set {
+ margin: 0;
+ }
+ }
+
+ // Tabbed button
+ .tabbed-button {
+ display: block;
+ align-self: center;
+ width: px2rem(18px);
+ height: px2rem(18px);
+ margin-top: px2rem(2px);
+ color: var(--md-default-fg-color--light);
+ pointer-events: initial;
+ cursor: pointer;
+ border-radius: 100%;
+ transition: background-color 250ms;
+
+ // Tabbed button on hover
+ &:hover {
+ color: var(--md-accent-fg-color);
+ background-color: var(--md-accent-fg-color--transparent);
+ }
+
+ // Tabbed button icon
+ &::after {
+ display: block;
+ width: 100%;
+ height: 100%;
+ content: "";
+ background-color: currentcolor;
+ transition:
+ background-color 250ms,
+ transform 250ms;
+ mask-image: var(--md-tabbed-icon--prev);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+ }
+
+ // Tabbed control
+ .tabbed-control {
+ position: absolute;
+ display: flex;
+ justify-content: start;
+ width: px2rem(24px);
+ height: px2rem(38px);
+ pointer-events: none;
+ background:
+ linear-gradient(
+ to right,
+ var(--md-default-bg-color) 60%,
+ transparent
+ );
+ transition: opacity 125ms;
+
+ // Adjust for right-to-left languages
+ [dir="rtl"] & {
+ transform: rotate(180deg);
+ }
+
+ // Tabbed control is hidden
+ &[hidden] {
+ opacity: 0;
+ }
+
+ // Tabbed control next
+ &--next {
+ right: 0;
+ justify-content: end;
+ background:
+ linear-gradient(
+ to left,
+ var(--md-default-bg-color) 60%,
+ transparent
+ );
+
+ // Tabbed button icon content
+ .tabbed-button::after {
+ mask-image: var(--md-tabbed-icon--next);
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Rules: top-level
+// ----------------------------------------------------------------------------
+
+// [mobile -]: Align with body copy
+@include break-to-device(mobile) {
+
+ // Top-level tabbed labels
+ .md-content__inner > .tabbed-set .tabbed-labels {
+ max-width: 100vw;
+ padding-inline-start: px2rem(16px);
+ margin: 0 px2rem(-16px);
+ scroll-padding-inline-start: px2rem(16px);
+
+ // Hack: some browsers ignore the right padding on flex containers,
+ // see https://bit.ly/3lsPS3S
+ &::after {
+ padding-inline-end: px2rem(16px);
+ content: "";
+ }
+
+ // Tabbed control previous
+ ~ .tabbed-control--prev {
+ width: px2rem(40px);
+ padding-inline-start: px2rem(16px);
+ margin-inline-start: px2rem(-16px);
+ }
+
+ // Tabbed control next
+ ~ .tabbed-control--next {
+ width: px2rem(40px);
+ padding-inline-end: px2rem(16px);
+ margin-inline-end: px2rem(-16px);
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Placeholders: improve colocation for better compression
+// ----------------------------------------------------------------------------
+
+// Tab label placeholder
+%tabbed-label {
+
+ // [screen]: Show active state
+ @media screen {
+ color: var(--md-default-fg-color);
+
+ // [no-js]: Show border (indicator is animated with JavaScript)
+ .no-js & {
+ border-color: var(--md-default-fg-color);
+ }
+ }
+}
+
+// Tab label on keyboard focus placeholder
+%tabbed-label-focus-visible {
+ color: var(--md-accent-fg-color);
+}
+
+// Tab content placeholder
+%tabbed-content {
+ display: block;
+}
diff --git a/src/templates/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss b/src/templates/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss
new file mode 100644
index 00000000..a1d1117c
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss
@@ -0,0 +1,78 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Tasklist variables
+:root {
+ --md-tasklist-icon: svg-load("octicons/check-circle-fill-24.svg");
+ --md-tasklist-icon--checked: svg-load("octicons/check-circle-fill-24.svg");
+}
+
+// ----------------------------------------------------------------------------
+
+// Scoped in typesetted content to match specificity of regular content
+.md-typeset {
+
+ // Tasklist item
+ .task-list-item {
+ position: relative;
+ list-style-type: none;
+
+ // Make checkbox items align with normal list items, but position
+ // everything in ems for correct layout at smaller font sizes
+ [type="checkbox"] {
+ position: absolute;
+ top: 0.45em;
+ inset-inline-start: -2em;
+ }
+ }
+
+ // Hide native checkbox, when custom classes are enabled
+ .task-list-control [type="checkbox"] {
+ z-index: -1;
+ opacity: 0;
+ }
+
+ // Tasklist indicator in unchecked state
+ .task-list-indicator::before {
+ position: absolute;
+ top: 0.15em;
+ width: px2em(20px);
+ height: px2em(20px);
+ content: "";
+ background-color: var(--md-default-fg-color--lightest);
+ inset-inline-start: px2em(-24px);
+ mask-image: var(--md-tasklist-icon);
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ }
+
+ // Tasklist indicator in checked state
+ [type="checkbox"]:checked + .task-list-indicator::before {
+ background-color: $clr-green-a400;
+ mask-image: var(--md-tasklist-icon--checked);
+ }
+}
diff --git a/src/templates/assets/stylesheets/main/integrations/_mermaid.scss b/src/templates/assets/stylesheets/main/integrations/_mermaid.scss
new file mode 100644
index 00000000..d0325f39
--- /dev/null
+++ b/src/templates/assets/stylesheets/main/integrations/_mermaid.scss
@@ -0,0 +1,67 @@
+////
+/// Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com>
+///
+/// Permission is hereby granted, free of charge, to any person obtaining a
+/// copy of this software and associated documentation files (the "Software"),
+/// to deal in the Software without restriction, including without limitation
+/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+/// and/or sell copies of the Software, and to permit persons to whom the
+/// Software is furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+/// DEALINGS
+////
+
+// ----------------------------------------------------------------------------
+// Rules
+// ----------------------------------------------------------------------------
+
+// Mermaid variables
+:root > * {
+ --md-mermaid-font-family: var(--md-text-font-family), sans-serif;
+
+ // General colors
+ --md-mermaid-edge-color: var(--md-code-fg-color);
+ --md-mermaid-node-bg-color: var(--md-accent-fg-color--transparent);
+ --md-mermaid-node-fg-color: var(--md-accent-fg-color);
+ --md-mermaid-label-bg-color: var(--md-default-bg-color);
+ --md-mermaid-label-fg-color: var(--md-code-fg-color);
+
+ // Sequence diagram colors
+ --md-mermaid-sequence-actor-bg-color: var(--md-mermaid-label-bg-color);
+ --md-mermaid-sequence-actor-fg-color: var(--md-mermaid-label-fg-color);
+ --md-mermaid-sequence-actor-border-color: var(--md-mermaid-node-fg-color);
+ --md-mermaid-sequence-actor-line-color: var(--md-default-fg-color--lighter);
+ --md-mermaid-sequence-actorman-bg-color: var(--md-mermaid-label-bg-color);
+ --md-mermaid-sequence-actorman-line-color: var(--md-mermaid-node-fg-color);
+ --md-mermaid-sequence-box-bg-color: var(--md-mermaid-node-bg-color);
+ --md-mermaid-sequence-box-fg-color: var(--md-mermaid-edge-color);
+ --md-mermaid-sequence-label-bg-color: var(--md-mermaid-node-bg-color);
+ --md-mermaid-sequence-label-fg-color: var(--md-mermaid-node-fg-color);
+ --md-mermaid-sequence-loop-bg-color: var(--md-mermaid-node-bg-color);
+ --md-mermaid-sequence-loop-fg-color: var(--md-mermaid-edge-color);
+ --md-mermaid-sequence-loop-border-color: var(--md-mermaid-node-fg-color);
+ --md-mermaid-sequence-message-fg-color: var(--md-mermaid-edge-color);
+ --md-mermaid-sequence-message-line-color: var(--md-mermaid-edge-color);
+ --md-mermaid-sequence-note-bg-color: var(--md-mermaid-label-bg-color);
+ --md-mermaid-sequence-note-fg-color: var(--md-mermaid-edge-color);
+ --md-mermaid-sequence-note-border-color: var(--md-mermaid-label-fg-color);
+ --md-mermaid-sequence-number-bg-color: var(--md-mermaid-node-fg-color);
+ --md-mermaid-sequence-number-fg-color: var(--md-accent-bg-color);
+}
+
+// ----------------------------------------------------------------------------
+
+// Mermaid container
+.mermaid {
+ margin: 1em 0;
+ line-height: normal;
+}