540 lines
17 KiB
CSS
540 lines
17 KiB
CSS
.md-typeset .highlight,
|
|
.md-typeset .highlight pre,
|
|
.md-typeset .highlight code {
|
|
background-color: #000;
|
|
color: #fff;
|
|
}
|
|
|
|
/* --- Section heading hierarchy -------------------------------------------
|
|
*
|
|
* Goals:
|
|
* - Every heading level is noticeably larger than its body text.
|
|
* - Higher-level headings are progressively larger than lower ones.
|
|
* - H1 is prominent but not oversized.
|
|
* - Lower-level headings (H4-H6) are bold/italic so they still read as
|
|
* headings even though their absolute size is smaller.
|
|
*
|
|
* Base body text in .md-typeset is 0.8 rem (~12.8 px).
|
|
* The scale below keeps every heading clearly above that baseline while
|
|
* maintaining a visible step between adjacent levels.
|
|
* ----------------------------------------------------------------------- */
|
|
|
|
.md-typeset h1 {
|
|
font-size: 2em; /* ~25.6 px */
|
|
font-weight: 700;
|
|
letter-spacing: -0.02em;
|
|
line-height: 1.25;
|
|
margin: 0 0 0.75em;
|
|
color: var(--md-default-fg-color);
|
|
}
|
|
|
|
.md-typeset h2 {
|
|
font-size: 1.7em; /* ~21.8 px */
|
|
font-weight: 600;
|
|
letter-spacing: -0.015em;
|
|
line-height: 1.3;
|
|
margin: 1.4em 0 0.6em;
|
|
border-bottom: 1px solid var(--md-default-fg-color--lightest);
|
|
padding-bottom: 0.3em;
|
|
}
|
|
|
|
.md-typeset h3 {
|
|
font-size: 1.4em; /* ~17.9 px */
|
|
font-weight: 600;
|
|
letter-spacing: -0.01em;
|
|
line-height: 1.35;
|
|
margin: 1.4em 0 0.6em;
|
|
border-bottom: 1px solid var(--md-default-fg-color--lightest);
|
|
padding-bottom: 0.3em;
|
|
}
|
|
|
|
.md-typeset h4 {
|
|
font-size: 1.2em; /* ~15.4 px */
|
|
font-weight: 700;
|
|
line-height: 1.4;
|
|
margin: 1.2em 0 0.5em;
|
|
border-bottom: 1px solid var(--md-default-fg-color--lightest);
|
|
padding-bottom: 0.3em;
|
|
}
|
|
|
|
.md-typeset h5 {
|
|
font-size: 1.15em; /* ~14.7 px */
|
|
font-weight: 700;
|
|
font-style: italic;
|
|
text-transform: none;
|
|
line-height: 1.4;
|
|
margin: 1.2em 0 0.4em;
|
|
border-bottom: 1px solid var(--md-default-fg-color--lightest);
|
|
padding-bottom: 0.3em;
|
|
}
|
|
|
|
.md-typeset h6 {
|
|
font-size: 1.1em; /* ~14.1 px */
|
|
font-weight: 700;
|
|
font-style: italic;
|
|
text-transform: none;
|
|
letter-spacing: 0.01em;
|
|
line-height: 1.4;
|
|
margin: 1.1em 0 0.4em;
|
|
border-bottom: 1px solid var(--md-default-fg-color--lightest);
|
|
padding-bottom: 0.3em;
|
|
color: var(--md-default-fg-color);
|
|
}
|
|
|
|
/* --- Compact table cells --------------------------------------------------
|
|
*
|
|
* MkDocs Material's default table padding is generous. Tighten it so
|
|
* wide tables (e.g. the automation-profile matrix) render without
|
|
* forcing column headers to word-wrap.
|
|
* ----------------------------------------------------------------------- */
|
|
|
|
/* First column never wraps — sized to its content. */
|
|
.md-typeset table:not([class]) th:first-child,
|
|
.md-typeset table:not([class]) td:first-child {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.md-typeset table:not([class]) th {
|
|
min-width: 0;
|
|
}
|
|
|
|
/* --- Navbar dropdown menus ---------------------------------------------------
|
|
*
|
|
* Custom tabs.html renders top-level sections (Development, Reference, ADRs)
|
|
* as tabs with hover-activated dropdown menus listing their child pages.
|
|
* Single-page tabs (Specification, Timeline, FAQ) have no dropdown.
|
|
* ----------------------------------------------------------------------- */
|
|
|
|
/* Override Material's overflow/containment on the tabs bar and its list.
|
|
* Material sets overflow:auto and contain:content which clip absolutely-
|
|
* positioned children (our dropdown menus). We need visible overflow
|
|
* so the dropdowns can extend below the tab bar.
|
|
*
|
|
* Material's selectors:
|
|
* .md-tabs { overflow: auto } — (0,1,0)
|
|
* .md-tabs__list { contain: content; overflow: auto } — (0,1,0)
|
|
*
|
|
* Counter-selectors beat them by nesting under .md-header: */
|
|
.md-header .md-tabs {
|
|
overflow: visible;
|
|
}
|
|
|
|
.md-header .md-tabs .md-tabs__list {
|
|
overflow: visible;
|
|
contain: none;
|
|
}
|
|
|
|
/* Dropdown container — positioned below the tab item */
|
|
.md-tabs__item--dropdown {
|
|
position: relative;
|
|
}
|
|
|
|
.md-tabs__dropdown {
|
|
display: none;
|
|
position: absolute;
|
|
top: 100%;
|
|
left: 0;
|
|
min-width: 16rem;
|
|
max-height: 70vh;
|
|
overflow-y: auto;
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: .4rem 0;
|
|
background: var(--md-primary-fg-color);
|
|
border-radius: 0 0 .2rem .2rem;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
|
|
z-index: 100;
|
|
}
|
|
|
|
/* Show dropdown on hover and when the tab is focused within */
|
|
.md-tabs__item--dropdown:hover > .md-tabs__dropdown,
|
|
.md-tabs__item--dropdown:focus-within > .md-tabs__dropdown {
|
|
display: block;
|
|
}
|
|
|
|
/* Dropdown link items */
|
|
.md-tabs__dropdown-link {
|
|
display: block;
|
|
padding: .4rem 1rem;
|
|
color: var(--md-primary-bg-color);
|
|
font-size: .7rem;
|
|
white-space: nowrap;
|
|
text-decoration: none;
|
|
transition: background-color .15s;
|
|
}
|
|
|
|
.md-tabs__dropdown-link:hover {
|
|
background-color: rgba(255, 255, 255, 0.15);
|
|
}
|
|
|
|
.md-tabs__dropdown-link--active {
|
|
font-weight: 700;
|
|
}
|
|
|
|
/* Nested section groups inside the dropdown */
|
|
.md-tabs__dropdown-group {
|
|
list-style: none;
|
|
}
|
|
|
|
.md-tabs__dropdown-label {
|
|
display: block;
|
|
padding: .5rem 1rem .2rem;
|
|
font-size: .6rem;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: .05em;
|
|
opacity: .7;
|
|
color: var(--md-primary-bg-color);
|
|
}
|
|
|
|
.md-tabs__dropdown-group > ul {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
/* Small caret indicator on tabs that have dropdowns */
|
|
.md-tabs__dropdown-caret {
|
|
display: inline-block;
|
|
width: 0;
|
|
height: 0;
|
|
margin-left: .3rem;
|
|
vertical-align: middle;
|
|
border-left: .25rem solid transparent;
|
|
border-right: .25rem solid transparent;
|
|
border-top: .25rem solid currentcolor;
|
|
opacity: .6;
|
|
}
|
|
|
|
/* --- Left sidebar: show only the TOC (desktop) --------------------------------
|
|
*
|
|
* With navigation.tabs + toc.integrate, the left sidebar contains both the
|
|
* sub-page navigation for the active tab AND the integrated TOC for the
|
|
* current page. We hide all non-TOC elements so the left sidebar displays
|
|
* only the Table of Contents.
|
|
*
|
|
* The TOC is always rendered inside <nav class="md-nav--secondary">.
|
|
* Everything else in the primary sidebar is page navigation.
|
|
*
|
|
* DESKTOP ONLY (>= 76.25em) — on mobile, the drawer navigation is used
|
|
* and must remain fully functional.
|
|
* ----------------------------------------------------------------------- */
|
|
|
|
@media screen and (min-width: 76.25em) {
|
|
/* Hide all top-level nav items in the sidebar — these are the page
|
|
* links within the active tab section (or the tab items themselves
|
|
* if the tab has no children). */
|
|
.md-sidebar--primary .md-nav--primary > .md-nav__list > .md-nav__item {
|
|
display: none;
|
|
}
|
|
|
|
/* But show items on the ancestor path to the current page — these
|
|
* contain the nested .md-nav--secondary (TOC). */
|
|
.md-sidebar--primary .md-nav--primary > .md-nav__list > .md-nav__item--active {
|
|
display: block;
|
|
}
|
|
|
|
/* Within active section wrappers, hide sibling page links (only the
|
|
* active child with its TOC should be visible).
|
|
*
|
|
* IMPORTANT: the :not(.md-nav--secondary) guard prevents this rule
|
|
* from also matching .md-nav--secondary (the TOC nav), whose <li>
|
|
* children are plain .md-nav__item without --active and would
|
|
* otherwise be hidden. */
|
|
.md-sidebar--primary .md-nav__item--active > .md-nav:not(.md-nav--secondary) > .md-nav__list > .md-nav__item:not(.md-nav__item--active) {
|
|
display: none;
|
|
}
|
|
|
|
/* Hide the page-link labels / headings on active items so only the
|
|
* TOC tree remains visible. This targets:
|
|
* - Section headings (<label class="md-nav__link">)
|
|
* - Page links (<a class="md-nav__link">)
|
|
* - The __toc checkbox and its label
|
|
* - The section title inside nested navs
|
|
* but NOT anything inside .md-nav--secondary (the TOC itself). */
|
|
.md-sidebar--primary .md-nav--primary > .md-nav__list > .md-nav__item--active > .md-nav__toggle,
|
|
.md-sidebar--primary .md-nav--primary > .md-nav__list > .md-nav__item--active > label.md-nav__link,
|
|
.md-sidebar--primary .md-nav--primary > .md-nav__list > .md-nav__item--active > a.md-nav__link,
|
|
.md-sidebar--primary .md-nav--primary > .md-nav__list > .md-nav__item--active > .md-nav__container,
|
|
.md-sidebar--primary .md-nav--primary > .md-nav__list > .md-nav__item--active > nav > .md-nav__title {
|
|
display: none;
|
|
}
|
|
|
|
/* Within nested sections (level 2+), hide the active page's own link
|
|
* and __toc machinery, leaving only the .md-nav--secondary TOC. */
|
|
.md-sidebar--primary .md-nav__item--active > #__toc,
|
|
.md-sidebar--primary .md-nav__item--active > label[for="__toc"],
|
|
.md-sidebar--primary .md-nav__item--active > a.md-nav__link,
|
|
.md-sidebar--primary .md-nav__item--active > .md-nav__container {
|
|
display: none;
|
|
}
|
|
|
|
/* Force the TOC (md-nav--secondary) visible.
|
|
*
|
|
* Material's rules that hide or collapse the TOC:
|
|
*
|
|
* A) .md-nav--primary .md-nav__link[for=__toc]~.md-nav
|
|
* → display: none — (0,4,0)
|
|
*
|
|
* B) .md-nav__toggle~.md-nav (desktop media query)
|
|
* → display: grid; opacity: 0; visibility: collapse — (0,2,0)
|
|
*
|
|
* Material's integrated rule tries to re-show it:
|
|
* C) .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary
|
|
* → display: block; opacity: 1; visibility: visible — (0,4,0)
|
|
*
|
|
* A and C tie at (0,4,0), so cascade order decides — and A often
|
|
* wins. We counter with higher-specificity selectors that
|
|
* guarantee the TOC is always visible without using !important.
|
|
*/
|
|
|
|
/* Counter rule A — specificity (0,6,0) beats (0,4,0).
|
|
* Directly negates the sibling-combinator hiding rule. */
|
|
.md-sidebar--primary .md-nav--primary .md-nav__link[for="__toc"] ~ nav.md-nav--secondary {
|
|
display: block;
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
/* General fallback for integrated mode — specificity (0,5,0)
|
|
* beats rule B (0,2,0) and ties/beats rule C (0,4,0) by being
|
|
* loaded later. */
|
|
.md-sidebar--primary .md-nav--primary.md-nav--integrated .md-nav__item--active .md-nav--secondary {
|
|
display: block;
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
/* Remove the top-level sidebar title ("Navigation" label) on desktop
|
|
* since we no longer show page navigation in the sidebar. */
|
|
.md-sidebar--primary .md-nav--primary > .md-nav__title {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* --- Collapsible TOC in integrated sidebar --- */
|
|
|
|
/* Container for the link row: link text + toggle chevron side by side.
|
|
* Scoped to .md-nav--secondary (active page TOC) so it does not affect
|
|
* primary nav section headings which use Material's native <label> +
|
|
* checkbox. */
|
|
.md-nav--secondary .md-nav__item--nested > .md-nav__link {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
/* Chevron toggle button injected by JS into TOC sub-items.
|
|
* Styled to match Material's native .md-nav__icon chevron exactly so
|
|
* all expand/collapse indicators look the same across the sidebar. */
|
|
.toc-toggle {
|
|
flex-shrink: 0;
|
|
width: .9rem;
|
|
height: .9rem;
|
|
margin-left: auto;
|
|
cursor: pointer;
|
|
border: none;
|
|
background: none;
|
|
border-radius: 100%;
|
|
transition: background-color .25s;
|
|
}
|
|
|
|
.toc-toggle:hover {
|
|
background-color: var(--md-accent-fg-color--transparent);
|
|
}
|
|
|
|
/* Use the same SVG mask-image chevron as Material's .md-nav__icon::after */
|
|
.toc-toggle::after {
|
|
content: "";
|
|
display: inline-block;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: currentcolor;
|
|
border-radius: 100%;
|
|
-webkit-mask-image: var(--md-nav-icon--next);
|
|
mask-image: var(--md-nav-icon--next);
|
|
-webkit-mask-position: center;
|
|
mask-position: center;
|
|
-webkit-mask-repeat: no-repeat;
|
|
mask-repeat: no-repeat;
|
|
-webkit-mask-size: contain;
|
|
mask-size: contain;
|
|
vertical-align: -.1rem;
|
|
transition: transform .25s;
|
|
/* Default: expanded (pointing down) */
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
/* Rotate arrow to point right when collapsed */
|
|
.toc-collapsed > .md-nav__link > .toc-toggle::after {
|
|
transform: rotate(0deg);
|
|
}
|
|
|
|
/* Hide/show nested nav list when collapsed (TOC items only).
|
|
* Desktop only — on mobile the TOC is rendered within Material's drawer
|
|
* and must remain in the render tree for correct scroll behaviour. */
|
|
@media screen and (min-width: 76.25em) {
|
|
.md-nav--secondary .md-nav__item--nested.toc-collapsed > .md-nav {
|
|
display: none;
|
|
}
|
|
|
|
.md-nav--secondary .md-nav__item--nested > .md-nav {
|
|
display: block;
|
|
}
|
|
}
|
|
|
|
/* --- Mobile sidebar scroll fix -----------------------------------------------
|
|
*
|
|
* On mobile (< 76.25em), Material renders the primary sidebar as a
|
|
* slide-out drawer. The custom toc-collapse.js script (which is
|
|
* desktop-only) restructures nav items and collapses sections, but on
|
|
* mobile we rely on Material's native drawer navigation. Ensure the
|
|
* drawer's content is scrollable when there are more items than fit on
|
|
* screen — this was broken because the desktop-only display:none rules
|
|
* were interfering with the scroll container height computation, and
|
|
* the nav containers lacked explicit overflow declarations.
|
|
* ----------------------------------------------------------------------- */
|
|
|
|
@media screen and (max-width: 76.1875em) {
|
|
/* Ensure the sidebar drawer inner wrapper scrolls vertically */
|
|
.md-sidebar--primary .md-sidebar__inner {
|
|
overflow-y: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
/* Ensure each nav level within the mobile drawer can scroll when it
|
|
* exceeds the viewport height. Material uses absolute positioning
|
|
* and transforms for the drill-down layers; this ensures each layer
|
|
* is independently scrollable. */
|
|
.md-sidebar--primary .md-nav__list {
|
|
overflow-y: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
/* Prevent the overall nav from clipping its children —
|
|
* Material's mobile drawer needs visible overflow on the
|
|
* horizontal axis for the slide animation, and auto on the
|
|
* vertical axis for scrolling. */
|
|
.md-sidebar--primary .md-nav--primary {
|
|
overflow: visible;
|
|
}
|
|
|
|
/* Undo any items hidden by the JS-driven toc-collapsed class that
|
|
* may have been applied before the mobile guard kicks in (race
|
|
* condition on resize or orientation change).
|
|
*
|
|
* The desktop hiding rule is:
|
|
* .md-nav--secondary .md-nav__item--nested.toc-collapsed > .md-nav
|
|
* { display: none } — (0,3,0), inside a ≥76.25em media query
|
|
*
|
|
* This mobile rule applies inside a <76.1875em media query, so the
|
|
* two never conflict — no !important needed. We bump specificity
|
|
* slightly for safety against any other rules. */
|
|
.md-sidebar--primary .md-nav--secondary .toc-collapsed > .md-nav {
|
|
display: block;
|
|
}
|
|
}
|
|
|
|
/* --- Diagram lightbox (fullscreen on click) --------------------------------
|
|
*
|
|
* Kroki diagrams (<img alt="Kroki">) get a pointer cursor to hint they are
|
|
* clickable. Clicking one opens a fullscreen overlay with the diagram
|
|
* scaled to fill the viewport. An X button or the Escape key closes it.
|
|
* ----------------------------------------------------------------------- */
|
|
|
|
/* Make diagram images look clickable */
|
|
img[alt="Kroki"] {
|
|
cursor: zoom-in;
|
|
transition: opacity 0.15s ease;
|
|
}
|
|
|
|
img[alt="Kroki"]:hover {
|
|
opacity: 0.85;
|
|
}
|
|
|
|
/* Fullscreen overlay */
|
|
.diagram-lightbox {
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 9999;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: rgba(0, 0, 0, 0.88);
|
|
backdrop-filter: blur(4px);
|
|
-webkit-backdrop-filter: blur(4px);
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: opacity 0.2s ease, visibility 0.2s ease;
|
|
padding: 2rem;
|
|
}
|
|
|
|
.diagram-lightbox.active {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
/* The enlarged diagram image */
|
|
.diagram-lightbox img {
|
|
max-width: 95vw;
|
|
max-height: 92vh;
|
|
object-fit: contain;
|
|
border-radius: 4px;
|
|
/* Invert for dark backgrounds so SVG lines stay visible */
|
|
filter: drop-shadow(0 2px 20px rgba(0, 0, 0, 0.5));
|
|
background: #fff;
|
|
padding: 1rem;
|
|
}
|
|
|
|
/* Close button */
|
|
.diagram-lightbox-close {
|
|
position: absolute;
|
|
top: 1rem;
|
|
right: 1.5rem;
|
|
width: 2.5rem;
|
|
height: 2.5rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: rgba(255, 255, 255, 0.15);
|
|
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
border-radius: 50%;
|
|
color: #fff;
|
|
font-size: 1.5rem;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
transition: background 0.15s ease, transform 0.15s ease;
|
|
z-index: 10000;
|
|
}
|
|
|
|
.diagram-lightbox-close:hover {
|
|
background: rgba(255, 255, 255, 0.3);
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
.diagram-lightbox-close:active {
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
/* ── ADR Admonition ──────────────────────────────────────────────── */
|
|
|
|
:root {
|
|
--md-admonition-icon--adr: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13zM6 20V4h5v7h7v9H6z"/><path d="M8 14h8v2H8zm0-3h8v2H8z"/></svg>');
|
|
}
|
|
|
|
.md-typeset .admonition.adr,
|
|
.md-typeset details.adr {
|
|
border-color: #7c4dff;
|
|
}
|
|
|
|
.md-typeset .adr > .admonition-title,
|
|
.md-typeset .adr > summary {
|
|
background-color: rgba(124, 77, 255, 0.1);
|
|
}
|
|
|
|
.md-typeset .adr > .admonition-title::before,
|
|
.md-typeset .adr > summary::before {
|
|
background-color: #7c4dff;
|
|
-webkit-mask-image: var(--md-admonition-icon--adr);
|
|
mask-image: var(--md-admonition-icon--adr);
|
|
}
|