This PR adds the ability to collapse section in the docs sidebar (which are persistent until you close the tab), and some design facelift to the docs, which makes its design close to the site as well as polishing up many elements and interactions (like moving the search to a modal and making the table of content visible in smaller breakpoints). <img width="600" height="2270" alt="Screenshot 2025-11-28 at 5 26@2x" src="https://github.com/user-attachments/assets/3a8606c6-f74f-4bd2-84c8-d7a67ff97564" /> Release Notes: - N/A
825 lines
15 KiB
CSS
825 lines
15 KiB
CSS
/* CSS for UI elements (a.k.a. chrome) */
|
||
|
||
@import "variables.css";
|
||
|
||
html {
|
||
background-color: var(--bg);
|
||
scrollbar-color: var(--scrollbar) var(--bg);
|
||
}
|
||
#searchresults a,
|
||
.content a:link,
|
||
a:visited,
|
||
a > .hljs {
|
||
color: var(--links);
|
||
}
|
||
|
||
.icon-logo-img {
|
||
display: block;
|
||
}
|
||
|
||
.icon-button {
|
||
position: relative;
|
||
height: 28px;
|
||
width: 28px;
|
||
z-index: 10;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
transition: color 0.5s;
|
||
border: 0;
|
||
background-color: transparent;
|
||
border-radius: 4px;
|
||
color: var(--icons);
|
||
}
|
||
|
||
.icon-button:hover {
|
||
color: var(--icons-hover);
|
||
background-color: var(--icon-btn-bg-hover);
|
||
}
|
||
|
||
.ib-hidden-desktop {
|
||
display: none;
|
||
}
|
||
|
||
.header-bar {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
padding: 12px 24px;
|
||
background-color: var(--sidebar-bg);
|
||
border-bottom: 1px solid var(--divider);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.header-bar .left-container {
|
||
width: 160px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.header-bar .right-container {
|
||
width: 160px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.logo-nav {
|
||
display: block;
|
||
filter: var(--logo-brightness);
|
||
}
|
||
|
||
.nav-chapters {
|
||
font-size: 2.5em;
|
||
text-align: center;
|
||
text-decoration: none;
|
||
|
||
position: fixed;
|
||
top: 0;
|
||
bottom: 0;
|
||
margin: 0;
|
||
max-width: 150px;
|
||
min-width: 90px;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-content: center;
|
||
flex-direction: column;
|
||
|
||
transition:
|
||
color 0.5s,
|
||
background-color 0.5s;
|
||
}
|
||
|
||
.nav-chapters:hover {
|
||
text-decoration: none;
|
||
background-color: var(--theme-hover);
|
||
transition:
|
||
background-color 0.15s,
|
||
color 0.15s;
|
||
}
|
||
|
||
.nav-wrapper {
|
||
margin-block-start: 50px;
|
||
display: none;
|
||
}
|
||
|
||
.footer-buttons {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 1rem;
|
||
padding: 24px 0;
|
||
}
|
||
|
||
.footer-button {
|
||
width: 100%;
|
||
padding: 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.5rem;
|
||
background-color: var(--footer-btn-bg);
|
||
border: 1px solid var(--footer-btn-border);
|
||
border-radius: 0.5rem;
|
||
font-size: 0.9em;
|
||
}
|
||
|
||
.footer-button:hover {
|
||
background-color: var(--footer-btn-bg-hover);
|
||
border-color: var(--footer-btn-border-hover);
|
||
}
|
||
|
||
.footer-button i {
|
||
text-decoration: underline !important;
|
||
text-decoration-color: transparent !important;
|
||
}
|
||
|
||
.mobile-nav-chapters {
|
||
font-size: 2.5em;
|
||
text-align: center;
|
||
text-decoration: none;
|
||
width: 90px;
|
||
border-radius: 5px;
|
||
background-color: var(--sidebar-bg);
|
||
}
|
||
|
||
/* Only Firefox supports flow-relative values */
|
||
.previous {
|
||
float: left;
|
||
}
|
||
[dir="rtl"] .previous {
|
||
float: right;
|
||
}
|
||
|
||
/* Only Firefox supports flow-relative values */
|
||
.next {
|
||
float: right;
|
||
right: var(--page-padding);
|
||
}
|
||
[dir="rtl"] .next {
|
||
float: left;
|
||
right: unset;
|
||
left: var(--page-padding);
|
||
}
|
||
|
||
/* Use the correct buttons for RTL layouts*/
|
||
[dir="rtl"] .previous i.fa-angle-left:before {
|
||
content: "\f105";
|
||
}
|
||
[dir="rtl"] .next i.fa-angle-right:before {
|
||
content: "\f104";
|
||
}
|
||
|
||
@media only screen and (max-width: 1080px) {
|
||
.nav-wide-wrapper {
|
||
display: none;
|
||
}
|
||
.nav-wrapper {
|
||
display: block;
|
||
}
|
||
}
|
||
|
||
/* sidebar-visible */
|
||
@media only screen and (max-width: 1380px) {
|
||
#sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper {
|
||
display: none;
|
||
}
|
||
#sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper {
|
||
display: block;
|
||
}
|
||
}
|
||
|
||
/* Inline code */
|
||
|
||
:not(pre) > .hljs {
|
||
display: inline;
|
||
padding: 0.1em 0.3em;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
:not(pre):not(a) > .hljs {
|
||
color: var(--inline-code-color);
|
||
overflow-x: initial;
|
||
}
|
||
|
||
a:hover > .hljs {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
pre {
|
||
background-color: var(--pre-bg);
|
||
border: 1px solid;
|
||
border-color: var(--pre-border);
|
||
box-shadow: var(--pre-shadow) 4px 4px 0px 0px;
|
||
position: relative;
|
||
}
|
||
pre > .hljs {
|
||
background-color: initial;
|
||
}
|
||
pre > .buttons {
|
||
position: absolute;
|
||
z-index: 100;
|
||
right: 0px;
|
||
top: 2px;
|
||
margin: 0px;
|
||
padding: 2px 0px;
|
||
|
||
color: var(--sidebar-fg);
|
||
cursor: pointer;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
transition:
|
||
visibility 0.1s linear,
|
||
opacity 0.1s linear;
|
||
}
|
||
pre:hover > .buttons {
|
||
visibility: visible;
|
||
opacity: 1;
|
||
}
|
||
pre > .buttons :hover {
|
||
color: var(--sidebar-active);
|
||
border-color: var(--border-hover);
|
||
background-color: var(--theme-hover);
|
||
}
|
||
pre > .buttons i {
|
||
margin-inline-start: 8px;
|
||
}
|
||
pre > .buttons button {
|
||
cursor: inherit;
|
||
margin: 0 4px;
|
||
height: 26px;
|
||
width: 26px;
|
||
font-size: 14px;
|
||
border-style: solid;
|
||
border-width: 1px;
|
||
border-radius: 4px;
|
||
border-color: var(--border);
|
||
background-color: var(--popover-bg);
|
||
transition: 100ms;
|
||
transition-property: color, border-color, background-color;
|
||
color: var(--icons);
|
||
}
|
||
|
||
pre > .playground {
|
||
border: none;
|
||
margin: 0;
|
||
box-shadow: none;
|
||
/* HACK: This serves to visually hide nested <pre> elements in "playground" code snippets.
|
||
A more robust solution would involve modifying the rendered HTML. */
|
||
}
|
||
|
||
@media (pointer: coarse) {
|
||
pre > .buttons button {
|
||
/* On mobile, make it easier to tap buttons. */
|
||
padding: 0.3rem 1rem;
|
||
}
|
||
|
||
.sidebar-resize-indicator {
|
||
/* Hide resize indicator on devices with limited accuracy */
|
||
display: none;
|
||
}
|
||
}
|
||
pre > code {
|
||
display: block;
|
||
padding: 1rem;
|
||
}
|
||
|
||
/* TODO: ACE editors overlap their buttons because ACE does absolute
|
||
positioning within the code block which breaks padding. The only solution I
|
||
can think of is to move the padding to the outer pre tag (or insert a div
|
||
wrapper), but that would require fixing a whole bunch of CSS rules.
|
||
*/
|
||
.hljs.ace_editor {
|
||
padding: 0rem 0rem;
|
||
}
|
||
|
||
pre > .result {
|
||
margin-block-start: 10px;
|
||
}
|
||
|
||
/* Search */
|
||
|
||
#searchresults a {
|
||
text-decoration: none;
|
||
}
|
||
|
||
mark {
|
||
border-radius: 2px;
|
||
padding-block-start: 0;
|
||
padding-block-end: 1px;
|
||
padding-inline-start: 3px;
|
||
padding-inline-end: 3px;
|
||
margin-block-start: 0;
|
||
margin-block-end: -1px;
|
||
margin-inline-start: -3px;
|
||
margin-inline-end: -3px;
|
||
background-color: var(--search-mark-bg);
|
||
transition: background-color 300ms linear;
|
||
cursor: pointer;
|
||
}
|
||
|
||
mark.fade-out {
|
||
background-color: rgba(0, 0, 0, 0) !important;
|
||
cursor: auto;
|
||
}
|
||
|
||
.searchbar-outer {
|
||
margin-inline-start: auto;
|
||
margin-inline-end: auto;
|
||
max-width: var(--content-max-width);
|
||
}
|
||
|
||
#searchbar {
|
||
width: 100%;
|
||
margin-block-start: 5px;
|
||
margin-block-end: 0;
|
||
margin-inline-start: auto;
|
||
margin-inline-end: auto;
|
||
padding: 10px 16px;
|
||
transition: box-shadow 300ms ease-in-out;
|
||
border: 1px solid var(--searchbar-border-color);
|
||
border-radius: 3px;
|
||
background-color: var(--searchbar-bg);
|
||
color: var(--searchbar-fg);
|
||
}
|
||
#searchbar:focus,
|
||
#searchbar.active {
|
||
box-shadow: 0 0 3px var(--searchbar-shadow-color);
|
||
outline: none;
|
||
border-color: var(--search-mark-bg);
|
||
}
|
||
|
||
.searchresults-header {
|
||
font-weight: bold;
|
||
font-size: 1em;
|
||
padding-block-start: 18px;
|
||
padding-block-end: 0;
|
||
padding-inline-start: 5px;
|
||
padding-inline-end: 0;
|
||
color: var(--searchresults-header-fg);
|
||
}
|
||
|
||
.searchresults-outer {
|
||
margin-inline-start: auto;
|
||
margin-inline-end: auto;
|
||
max-width: var(--content-max-width);
|
||
border-block-end: 1px dashed var(--searchresults-border-color);
|
||
}
|
||
|
||
ul#searchresults {
|
||
list-style: none;
|
||
padding-inline-start: 20px;
|
||
}
|
||
ul#searchresults li {
|
||
margin: 10px 0px;
|
||
padding: 2px;
|
||
border-radius: 2px;
|
||
}
|
||
ul#searchresults li.focus {
|
||
background-color: var(--searchresults-li-bg);
|
||
}
|
||
ul#searchresults span.teaser {
|
||
display: block;
|
||
clear: both;
|
||
margin-block-start: 5px;
|
||
margin-block-end: 0;
|
||
margin-inline-start: 20px;
|
||
margin-inline-end: 0;
|
||
font-size: 0.8em;
|
||
}
|
||
ul#searchresults span.teaser em {
|
||
font-weight: bold;
|
||
font-style: normal;
|
||
}
|
||
|
||
/* Sidebar */
|
||
|
||
.sidebar {
|
||
position: relative;
|
||
width: var(--sidebar-width);
|
||
flex-shrink: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
font-size: 0.875em;
|
||
box-sizing: border-box;
|
||
-webkit-overflow-scrolling: touch;
|
||
overscroll-behavior-y: none;
|
||
overflow: hidden;
|
||
background-color: var(--sidebar-bg);
|
||
color: var(--sidebar-fg);
|
||
border-right: 1px solid var(--divider);
|
||
}
|
||
|
||
[dir="rtl"] .sidebar {
|
||
left: unset;
|
||
right: 0;
|
||
}
|
||
.sidebar-resizing {
|
||
-moz-user-select: none;
|
||
-webkit-user-select: none;
|
||
-ms-user-select: none;
|
||
user-select: none;
|
||
}
|
||
.no-js .sidebar,
|
||
.js:not(.sidebar-resizing) .sidebar {
|
||
transition: transform 0.3s; /* Animation: slide away */
|
||
}
|
||
.sidebar code {
|
||
line-height: 2em;
|
||
}
|
||
.sidebar .sidebar-scrollbox {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
min-height: 0;
|
||
}
|
||
|
||
.sidebar .sidebar-resize-handle {
|
||
position: absolute;
|
||
cursor: col-resize;
|
||
width: 0;
|
||
right: calc(var(--sidebar-resize-indicator-width) * -1);
|
||
top: 0;
|
||
bottom: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.sidebar-resize-handle .sidebar-resize-indicator {
|
||
width: 100%;
|
||
height: 12px;
|
||
background-color: var(--icons);
|
||
margin-inline-start: var(--sidebar-resize-indicator-space);
|
||
}
|
||
|
||
[dir="rtl"] .sidebar .sidebar-resize-handle {
|
||
left: calc(var(--sidebar-resize-indicator-width) * -1);
|
||
right: unset;
|
||
}
|
||
.js .sidebar .sidebar-resize-handle {
|
||
cursor: col-resize;
|
||
width: calc(
|
||
var(--sidebar-resize-indicator-width) -
|
||
var(--sidebar-resize-indicator-space)
|
||
);
|
||
}
|
||
.sidebar::-webkit-scrollbar {
|
||
background: var(--sidebar-bg);
|
||
}
|
||
.sidebar::-webkit-scrollbar-thumb {
|
||
background: var(--scrollbar);
|
||
}
|
||
|
||
@media only screen and (max-width: 619px) {
|
||
.sidebar {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
height: 100vh;
|
||
padding-top: 57px; /* Account for header height */
|
||
transform: translateX(-100%);
|
||
z-index: 99;
|
||
transition: transform 0.1s ease;
|
||
}
|
||
|
||
[dir="rtl"] .sidebar {
|
||
left: unset;
|
||
right: 0;
|
||
transform: translateX(100%);
|
||
}
|
||
|
||
body.sidebar-open .sidebar {
|
||
transform: translateX(0);
|
||
}
|
||
}
|
||
|
||
@media only screen and (min-width: 620px) {
|
||
.sidebar {
|
||
position: relative;
|
||
}
|
||
}
|
||
|
||
.chapter {
|
||
list-style: none outside none;
|
||
padding: 8px 20px 20px 20px;
|
||
line-height: 2.2em;
|
||
margin: 0;
|
||
}
|
||
|
||
.chapter ol {
|
||
width: 100%;
|
||
}
|
||
|
||
.chapter li {
|
||
display: flex;
|
||
color: var(--sidebar-non-existant);
|
||
}
|
||
|
||
.chapter li a {
|
||
display: block;
|
||
padding: 0 4px;
|
||
text-decoration: none;
|
||
color: var(--sidebar-fg);
|
||
}
|
||
|
||
.chapter li a:hover {
|
||
color: var(--sidebar-active);
|
||
}
|
||
|
||
.chapter li a.active {
|
||
color: var(--sidebar-active);
|
||
background-color: var(--sidebar-active-bg);
|
||
}
|
||
|
||
.chapter li > a.toggle {
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-inline-start: auto;
|
||
user-select: none;
|
||
opacity: 0.5;
|
||
border-radius: 4px;
|
||
transition:
|
||
opacity 0.15s ease,
|
||
background-color 0.15s ease;
|
||
}
|
||
|
||
.chapter li > a.toggle:hover {
|
||
opacity: 1;
|
||
background-color: var(--theme-hover);
|
||
}
|
||
|
||
.chapter li.chapter-item {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
line-height: 1.5em;
|
||
margin-block-start: 0.6em;
|
||
}
|
||
|
||
.chapter li.chapter-item > a:first-child {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.chapter li.expanded > a.toggle div {
|
||
transform: rotate(90deg);
|
||
}
|
||
|
||
.chapter li.part-title {
|
||
font-size: 1.4rem;
|
||
padding: 0 8px 0 4px;
|
||
color: var(--title-color);
|
||
cursor: pointer;
|
||
user-select: none;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
line-height: auto;
|
||
border-radius: 2px;
|
||
}
|
||
|
||
.chapter li.part-title.collapsible:hover {
|
||
background-color: var(--hover-section-title);
|
||
}
|
||
|
||
.chapter li.part-title.collapsible::after {
|
||
content: "❯";
|
||
display: inline-block;
|
||
font-size: 1.2rem;
|
||
opacity: 0.6;
|
||
transition: transform 0.2s ease;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.chapter li.part-title.collapsible.expanded::after {
|
||
transform: rotate(90deg);
|
||
}
|
||
|
||
.chapter li.section-spacer {
|
||
height: 2rem;
|
||
list-style: none;
|
||
}
|
||
|
||
.chapter li.section-hidden {
|
||
display: none !important;
|
||
}
|
||
|
||
.section {
|
||
list-style: none outside none;
|
||
padding-inline-start: 3ch;
|
||
line-height: 1.9em;
|
||
}
|
||
|
||
.theme-popup {
|
||
position: absolute;
|
||
right: 155px;
|
||
top: calc(var(--menu-bar-height) - 18px);
|
||
z-index: 1000;
|
||
border-radius: 4px;
|
||
font-size: 1.4rem;
|
||
color: var(--fg);
|
||
background: var(--popover-bg);
|
||
border: 1px solid var(--popover-border);
|
||
margin: 0;
|
||
padding: 0;
|
||
list-style: none;
|
||
display: none;
|
||
/* Don't let the children's background extend past the rounded corners. */
|
||
overflow: hidden;
|
||
}
|
||
|
||
[dir="rtl"] .theme-popup {
|
||
left: unset;
|
||
right: 10px;
|
||
}
|
||
.theme-popup .default {
|
||
color: var(--icons);
|
||
}
|
||
.theme-popup .theme {
|
||
width: 100%;
|
||
border: 0;
|
||
margin: 0;
|
||
padding: 2px 24px;
|
||
line-height: 25px;
|
||
white-space: nowrap;
|
||
text-align: start;
|
||
cursor: pointer;
|
||
color: inherit;
|
||
background: inherit;
|
||
font-size: inherit;
|
||
font-family: inherit;
|
||
}
|
||
.theme-popup .theme:hover {
|
||
background-color: var(--theme-hover);
|
||
}
|
||
|
||
.theme-selected::before {
|
||
font-family: Arial, Helvetica, sans-serif;
|
||
text-align: center;
|
||
display: inline-block;
|
||
content: "✓";
|
||
margin-inline-start: -20px;
|
||
width: 20px;
|
||
}
|
||
|
||
.download-button {
|
||
max-height: 28px;
|
||
margin-left: 8px;
|
||
background: var(--download-btn-bg);
|
||
color: var(--download-btn-color);
|
||
padding: 4px 8px;
|
||
border: 1px solid;
|
||
border-color: var(--download-btn-border);
|
||
font-size: 1.4rem;
|
||
border-radius: 4px;
|
||
box-shadow: var(--download-btn-shadow) 0px -2px 0px 0px inset;
|
||
text-decoration: none;
|
||
transition: 100ms;
|
||
transition-property: box-shadow, border-color, background-color;
|
||
}
|
||
|
||
.download-button:hover {
|
||
background: var(--download-btn-bg);
|
||
border-color: var(--download-btn-border-hover);
|
||
box-shadow: none;
|
||
}
|
||
|
||
.search-button {
|
||
min-width: 100px;
|
||
max-width: 300px;
|
||
height: 28px;
|
||
width: 100%;
|
||
padding: 4px 4px 4px 8px;
|
||
display: flex;
|
||
gap: 8px;
|
||
background: var(--search-btn-bg);
|
||
border: 1px solid;
|
||
border-color: var(--search-btn-border);
|
||
font-size: 1.4rem;
|
||
font-family: var(--font);
|
||
color: var(--icons);
|
||
border-radius: 4px;
|
||
transition: 100ms;
|
||
transition-property: box-shadow, border-color, background-color;
|
||
}
|
||
|
||
.search-button:hover {
|
||
background: var(--search-btn-bg-hover);
|
||
}
|
||
|
||
.search-button .icon {
|
||
width: 12px;
|
||
height: 12px;
|
||
transform: translateY(10%);
|
||
scale: 0.9;
|
||
}
|
||
|
||
.search-content-desktop {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.search-content-mobile {
|
||
display: none;
|
||
}
|
||
|
||
.search-container {
|
||
box-sizing: border-box;
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 1000;
|
||
padding: 24px;
|
||
padding-top: 72px;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
display: none;
|
||
justify-content: center;
|
||
}
|
||
|
||
.search-container:has(#search-wrapper:not(.hidden)) {
|
||
display: flex;
|
||
}
|
||
|
||
.search-modal {
|
||
box-sizing: border-box;
|
||
|
||
max-width: 600px;
|
||
min-width: 600px;
|
||
height: fit-content;
|
||
max-height: 600px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding: 16px;
|
||
overflow-y: auto;
|
||
|
||
border-radius: 8px;
|
||
background: var(--popover-bg);
|
||
border: 1px solid var(--popover-border);
|
||
box-shadow: var(--popover-shadow);
|
||
}
|
||
|
||
.searchbar-outer {
|
||
width: 100%;
|
||
}
|
||
|
||
@media only screen and (max-width: 780px) {
|
||
.header-bar {
|
||
padding: 16px;
|
||
justify-content: start;
|
||
}
|
||
|
||
.download-button {
|
||
display: none;
|
||
}
|
||
|
||
.ib-hidden-mobile {
|
||
display: none;
|
||
}
|
||
|
||
.header-bar .left-container {
|
||
width: fit-content;
|
||
}
|
||
|
||
.header-bar .right-container {
|
||
width: fit-content;
|
||
}
|
||
|
||
.search-button {
|
||
width: 100px;
|
||
margin-left: auto;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.ib-hidden-desktop {
|
||
display: block;
|
||
}
|
||
|
||
.search-modal {
|
||
width: 90vw;
|
||
min-width: auto;
|
||
}
|
||
|
||
.search-content-desktop {
|
||
display: none;
|
||
}
|
||
|
||
.search-content-mobile {
|
||
display: flex;
|
||
}
|
||
|
||
.sidebar {
|
||
box-shadow: var(--sidebar-mobile-shadow);
|
||
}
|
||
|
||
.theme-popup {
|
||
right: 15px;
|
||
}
|
||
}
|