/*
 * docs.css — documentation-site layout for ShaoFastRobots.
 *
 * Loaded after the Duckquill theme's style.css (via config.toml `extra.styles`),
 * so it wins the cascade. Everything here is scoped under `#docs-sidebar`,
 * `body:has(#docs-sidebar)`, or a `.docs-*` / `.lab-index` / `.profile` class so
 * it cannot leak into theme components.
 *
 * Colours come exclusively from the theme's custom properties, which means dark
 * and light mode both follow automatically.
 */

body:has(#docs-sidebar) {
	--docs-sidebar-width: 18rem;
	--docs-content-width: 56rem;
	/* Clears the sticky nav pill: 1rem inset + ~3.25rem tall + 1.25rem gap. */
	--docs-nav-clearance: 5.5rem;
	/* Opaque equivalent of the --fg-muted-1 rail tint. Needs to be opaque so the
	   sticky nav caption can hide list items scrolling underneath it. */
	--docs-sidebar-bg: color-mix(in srgb, var(--fg-color) 4%, var(--bg-color));
}

/* ---------------------------------------------------------------- layout ---- */

/* Replaces the theme's 3-column gutter grid (sass/_general.scss) with a
   fixed sidebar rail + flexible content column. */
body:has(#docs-sidebar) {
	grid-template-columns: var(--docs-sidebar-width) minmax(0, 1fr);
	grid-template-rows: auto minmax(auto, 1fr) auto;
	grid-template-areas:
		"nav nav"
		"sidebar main"
		"footer footer";
}

/* The nav pill spans the full width instead of being capped at 720px. */
body:has(#docs-sidebar) #site-nav {
	max-width: min(76rem, calc(100% - 3rem));
}

/* Beats `main { margin: 4.25rem auto 4rem; width: min(var(--container-width), 90%) }`. */
body:has(#docs-sidebar) main {
	grid-area: main;
	margin: 0;
	min-width: 0;
	width: 100%;
	max-width: var(--docs-content-width);
	padding: 1.25rem 2.5rem 5rem;
}

html.sidebar-hidden #docs-sidebar {
	display: none;
}

/* Collapse to a single column and centre the content column in the space. */
html.sidebar-hidden body:has(#docs-sidebar) {
	grid-template-columns: minmax(0, 1fr);
	grid-template-areas:
		"nav"
		"main"
		"footer";
}

html.sidebar-hidden body:has(#docs-sidebar) main {
	margin-inline: auto;
}

/* --------------------------------------------------------------- sidebar ---- */

/* Outer element stretches to form a full-height rail with a divider; the inner
   element is what sticks. Splitting the two lets the rail fill the row while
   still allowing sticky positioning (a stretched item has no room to slide). */
#docs-sidebar {
	grid-area: sidebar;
	border-inline-end: max(1px, 0.0625rem) solid var(--fg-muted-2);
	background-color: var(--docs-sidebar-bg);
}

#docs-sidebar .docs-sidebar-inner {
	display: flex;
	position: sticky;
	flex-direction: column;
	gap: 1rem;
	inset-block-start: var(--docs-nav-clearance);
	max-height: calc(100vh - var(--docs-nav-clearance));
	padding: 0.5rem 1rem 1rem;
	/* Deliberately not `overflow: auto` — that would clip the search dropdown.
	   Only .docs-nav scrolls. */
}

#docs-sidebar .docs-sidebar-head {
	display: flex;
	align-items: flex-start;
	gap: 0.5rem;
	border-block-end: max(1px, 0.0625rem) solid var(--fg-muted-2);
	padding-block-end: 0.75rem;
}

#docs-sidebar .docs-brand {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 0.5rem;
	align-items: flex-start;
	min-width: 0;
	color: inherit;
	text-decoration: none;
}

/* The SS chip. 44px in the sidebar; the spec's radius (17.6%) and letterform
   outlines are baked into the SVG, so only colour is set here.
   Light takes the primary lockup, dark takes the spec's inverse — an ink chip
   would otherwise sink into an ink page. */
#docs-sidebar .ss-mark {
	display: block;
	flex: none;
	border-radius: 17.6%;
	width: 44px;
	height: 44px;
}

.ss-chip {
	fill: #16181d;
}

.ss-letters {
	fill: var(--accent-color);
}

[data-theme="dark"] .ss-chip {
	fill: var(--accent-color);
}

[data-theme="dark"] .ss-letters {
	fill: #16181d;
}

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) .ss-chip {
		fill: var(--accent-color);
	}

	:root:not([data-theme="light"]) .ss-letters {
		fill: #16181d;
	}
}

/* Collapse (« in the sidebar header) and expand (» pinned to the page edge).
   Both are plain text glyphs, so they stay legible even if this stylesheet is
   stale or missing. */
#docs-sidebar .docs-sidebar-collapse,
.docs-sidebar-expand {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: var(--transition);
	box-shadow: none;
	border: none;
	background-color: var(--fg-muted-1);
	padding: 0;
	color: var(--fg-muted-5);
	font-weight: 700;
	font-size: var(--font-size-medium);
	line-height: 1;
	font-family: inherit;
	user-select: none;
}

#docs-sidebar .docs-sidebar-collapse:hover,
#docs-sidebar .docs-sidebar-collapse:focus-visible,
.docs-sidebar-expand:hover,
.docs-sidebar-expand:focus-visible {
	background-color: var(--fg-muted-2);
	color: var(--accent-color);
}

#docs-sidebar .docs-sidebar-collapse {
	border-radius: var(--rounded-corner-small);
	width: 1.875rem;
	height: 1.875rem;
}

/* Only present while the sidebar is hidden; a tab against the left edge, at the
   height the sidebar header used to occupy. */
.docs-sidebar-expand {
	display: none;
	position: fixed;
	z-index: 998;
	inset-block-start: var(--docs-nav-clearance, 5.5rem);
	inset-inline-start: 0;
	box-shadow: var(--edge-highlight);
	border-start-end-radius: var(--rounded-corner);
	border-end-end-radius: var(--rounded-corner);
	width: 1.75rem;
	height: 2.75rem;
}

html.sidebar-hidden .docs-sidebar-expand {
	display: flex;
}

#docs-sidebar .docs-brand:hover .docs-brand-title {
	color: var(--accent-color);
}

#docs-sidebar .docs-brand-title {
	transition: var(--transition);
	font-weight: 600;
	font-size: var(--font-size-medium);
	line-height: 1.3;
}

#docs-sidebar .docs-brand-subtitle {
	color: var(--fg-muted-5);
	font-size: var(--font-size-x-small);
}

/* Strip Duckquill's generic <details> treatment (rounded card, tinted fill,
   1rem padding) — the nav group is a plain list, not a disclosure card. */
#docs-sidebar .docs-nav-group,
#docs-sidebar .docs-nav-group[open] {
	margin-block-end: 0;
	box-shadow: none;
	border-radius: 0;
	background-color: transparent;
	padding: 0;
}

/* Section caption doubles as the <details> summary, and stays pinned while the
   list below it scrolls. Styled as a full-width control rather than a bare
   label: an uppercase muted caption reads as a heading, so nothing suggests it
   can be clicked to fold the list. */
#docs-sidebar .docs-nav-caption {
	display: flex;
	position: sticky;
	z-index: 1;
	align-items: center;
	cursor: pointer;
	inset-block-start: 0;
	transition: var(--transition);
	margin: 0 0 0.25rem;
	border-radius: var(--rounded-corner-small);
	background-color: var(--docs-sidebar-bg);
	padding: 0.4375rem 0.5rem;
	color: var(--fg-muted-5);
	font-weight: 600;
	font-size: var(--font-size-x-small);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	user-select: none;
}

#docs-sidebar .docs-nav-caption:hover,
#docs-sidebar .docs-nav-caption:focus-visible {
	background-color: var(--fg-muted-2);
	color: var(--fg-color);
}

/* Push the theme's disclosure chevron to the trailing edge, where a docs nav
   normally puts it, and size it to read as a control. It flips on [open] via
   the theme's own `transform: scaleY(-1)`. */
#docs-sidebar .docs-nav-caption::before {
	order: 1;
	margin-inline: auto 0;
	width: 0.9375rem;
	height: 0.9375rem;
	opacity: 0.9;
}

/* The one scrolling region. The scroll must sit on <details> itself, not on the
   inner <ul>: a <details> renders its content through a slot, so the <ul> is not
   a flex item of it and would never be constrained (it overflowed the rail).
   min-height:0 lets this shrink as a flex item of .docs-sidebar-inner. */
#docs-sidebar .docs-nav-group {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
}

#docs-sidebar .docs-nav,
#docs-sidebar .docs-nav-toc {
	margin: 0;
	padding: 0;
	list-style: none;
}

#docs-sidebar .docs-nav > li > a {
	display: block;
	transition: var(--transition);
	border-radius: var(--rounded-corner-small);
	padding: 0.375rem 0.5rem;
	color: inherit;
	font-weight: 400;
	font-size: var(--font-size-small);
	line-height: 1.35;
	text-decoration: none;
}

#docs-sidebar .docs-nav > li > a:hover {
	background-color: var(--fg-muted-2);
}

#docs-sidebar .docs-nav > li.current > a {
	background-color: var(--fg-muted-2);
	color: var(--accent-color);
	font-weight: 600;
}

/* Sub-headings of the current page. */
#docs-sidebar .docs-nav-toc {
	margin: 0.25rem 0 0.5rem 0.75rem;
	border-inline-start: max(2px, 0.125rem) solid var(--fg-muted-2);
	padding-inline-start: 0.5rem;
}

#docs-sidebar .docs-nav-toc a {
	display: block;
	transition: var(--transition);
	border-radius: var(--rounded-corner-small);
	padding: 0.1875rem 0.5rem;
	color: var(--fg-muted-5);
	font-size: var(--font-size-x-small);
	line-height: 1.4;
	text-decoration: none;
}

#docs-sidebar .docs-nav-toc a:hover {
	background-color: var(--fg-muted-2);
	color: var(--fg-color);
}

#docs-sidebar .docs-sidebar-foot {
	border-block-start: max(1px, 0.0625rem) solid var(--fg-muted-2);
	padding-block-start: 0.75rem;
}

#docs-sidebar .docs-sidebar-foot a {
	color: var(--fg-muted-5);
	font-size: var(--font-size-x-small);
	text-decoration: none;
}

#docs-sidebar .docs-sidebar-foot a:hover,
#docs-sidebar .docs-sidebar-foot a.current {
	color: var(--accent-color);
}

/* ---------------------------------------------------------------- search ---- */

/* The theme's search styles are nested inside `#site-nav`, so moving the markup
   into the sidebar means restyling it from scratch. No `.active` gating: the box
   is permanently visible and search-fuse.js enables it on load. */
#docs-sidebar #search-container {
	position: relative;
}

#docs-sidebar #search-bar {
	box-shadow: var(--edge-highlight);
	border: none;
	border-radius: 999px;
	background-color: var(--fg-muted-2);
	padding: 0 0.875rem;
	width: 100%;
	height: 2.25rem;
	color: inherit;
	font-family: inherit;
	font-size: var(--font-size-small);
}

#docs-sidebar #search-bar::placeholder {
	opacity: 1;
	color: var(--fg-muted-4);
}

#docs-sidebar #search-results-container {
	position: absolute;
	z-index: 998;
	inset-block-start: calc(100% + 0.5rem);
	inset-inline-start: 0;
	width: max(100%, 22rem);
}

/* Background lives on #search-results, not the container, so an empty result set
   (JS sets display:none) doesn't leave a floating blank panel. */
#docs-sidebar #search-results {
	-webkit-backdrop-filter: var(--blur);
	display: none;
	flex-direction: column;
	gap: 0.5rem;
	backdrop-filter: var(--blur);
	box-shadow: var(--edge-highlight), var(--shadow-glass);
	border-radius: var(--rounded-corner);
	background-color: var(--glass-bg);
	padding: 0.5rem;
	max-height: 60vh;
	overflow-y: auto;
	font-size: var(--font-size-small);
}

#docs-sidebar #search-results .item {
	display: inline-flex;
	flex-direction: column;
	box-shadow: var(--edge-highlight);
	border-radius: var(--rounded-corner-small);
	background-color: var(--fg-muted-1);
	padding: 0.5rem;
}

#docs-sidebar #search-results .item a {
	width: fit-content;
	font-weight: 600;
}

#docs-sidebar #search-results .item span {
	color: var(--fg-muted-5);
	font-size: var(--font-size-x-small);
}

#docs-sidebar #search-results .item span strong {
	color: var(--fg-color);
}

#docs-sidebar #search-results .item span:first-of-type,
#docs-sidebar #search-results .item span.more-matches {
	margin-block-start: 0.5rem;
	border-block-start: max(1px, 0.0625rem) solid var(--fg-muted-2);
	padding-block-start: 0.25rem;
}

/* ----------------------------------------------------------- breadcrumbs ---- */

.docs-breadcrumbs {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.25rem 0.5rem;
	margin-block-end: 1.5rem;
	border-block-end: max(1px, 0.0625rem) solid var(--fg-muted-2);
	padding-block-end: 0.75rem;
	color: var(--fg-muted-5);
	font-size: var(--font-size-small);
}

.docs-breadcrumbs ol {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.25rem 0.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.docs-breadcrumbs li + li::before {
	margin-inline-end: 0.5rem;
	color: var(--fg-muted-3);
	content: "›";
}

.docs-breadcrumbs a {
	text-decoration: none;
}

.docs-breadcrumbs a:hover {
	text-decoration: underline;
}

.docs-breadcrumbs .docs-breadcrumb-current {
	color: var(--fg-color);
}

.docs-breadcrumbs .docs-edit-link {
	margin-inline-start: auto;
	white-space: nowrap;
}

/* ------------------------------------------------------------ lab index ---- */

/* "Contents" heading above the list — a section label, not a link to decorate. */
.lab-index-heading {
	margin-block-end: 0;
}

.lab-index-heading a {
	color: inherit;
	text-decoration: none;
}

.lab-index-heading a:hover {
	color: var(--accent-color);
}

.lab-index {
	counter-reset: lab;
	margin: 1.5rem 0 0;
	border-block-start: max(1px, 0.0625rem) solid var(--fg-muted-2);
	padding: 0;
	list-style: none;
}

.lab-index > li {
	display: grid;
	grid-template-columns: 2.5rem minmax(0, 1fr);
	gap: 0 0.5rem;
	counter-increment: lab;
	transition: var(--transition);
	border-block-end: max(1px, 0.0625rem) solid var(--fg-muted-2);
	padding: 0.875rem 0.5rem;
}

.lab-index > li:hover {
	background-color: var(--fg-muted-1);
}

.lab-index > li::before {
	color: var(--fg-muted-4);
	font-variant-numeric: tabular-nums;
	font-size: var(--font-size-small);
	content: counter(lab) ".";
}

.lab-index .lab-index-title {
	font-weight: 600;
	text-decoration: none;
}

.lab-index .lab-index-title:hover {
	text-decoration: underline;
}

.lab-index .lab-index-description {
	grid-column: 2;
	margin: 0.25rem 0 0;
	color: var(--fg-muted-5);
	font-size: var(--font-size-small);
}

/* --------------------------------------------------------------- profile ---- */

.profile-heading {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem;
	margin-block-end: 1.5rem;
}

.profile-heading h1 {
	margin: 0;
}

.profile-links {
	display: flex;
	align-items: center;
	gap: 0.625rem;
}

.profile-links a {
	display: inline-flex;
	color: var(--accent-color);
}

.profile-links svg {
	width: 1.75rem;
	height: 1.75rem;
	fill: currentColor;
}

.profile {
	display: grid;
	grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
	align-items: start;
	gap: 1.5rem;
	margin-block-end: 2rem;
}

.profile img {
	display: block;
	width: 100%;
	height: auto;
	max-height: 15rem;
	object-fit: contain;
}

.profile-bio p:first-child {
	margin-block-start: 0;
}

.org-logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1.5rem;
	margin-block-end: 2.5rem;
}

.org-logos img {
	width: auto;
	max-width: 100%;
	height: 8rem;
	border: none;
	box-shadow: none;
	background-color: transparent;
}

@media only screen and (max-width: 620px) {
	.profile {
		grid-template-columns: minmax(0, 1fr);
	}

	.profile-photo {
		max-width: 15rem;
	}
}

/* --------------------------------------------------------- article header ---- */

/* Duckquill centres the article header and paints the h1 with a clipped gradient
   — a magazine treatment. Documentation titles sit left and solid. */
body:has(#docs-sidebar) #heading {
	margin: 0 0 1.75rem;
	text-align: start;
}

body:has(#docs-sidebar) #heading h1 {
	-webkit-background-clip: border-box;
	margin-block-end: 0.5rem;
	background-image: none;
	background-clip: border-box;
	color: var(--fg-color);
	font-size: var(--font-size-xx-large);
	line-height: 1.15;
}

/* Date and tag rows read as metadata under the title rather than a byline. */
body:has(#docs-sidebar) #heading > p {
	margin: 0;
	color: var(--fg-muted-5);
}

body:has(#docs-sidebar) #heading .tags {
	justify-content: flex-start;
	margin-block-start: 0.75rem;
}

/* Section and list pages get the same treatment as article titles. */
body:has(#docs-sidebar) main > h1 {
	margin-block-start: 0;
	font-size: var(--font-size-xx-large);
	line-height: 1.15;
}

/* ------------------------------------------------- redundant theme chrome ---- */

/* The sidebar supersedes the floating TOC popover. #go-to-top stays. */
body:has(#docs-sidebar) #buttons-container #toc,
body:has(#docs-sidebar) #buttons-container #share {
	display: none;
}

/* ------------------------------------------------------------ responsive ---- */

@media only screen and (max-width: 1100px) {
	body:has(#docs-sidebar) {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto auto minmax(auto, 1fr) auto;
		grid-template-areas:
			"nav"
			"sidebar"
			"main"
			"footer";
	}

	#docs-sidebar {
		border-inline-end: none;
		border-block-end: max(1px, 0.0625rem) solid var(--fg-muted-2);
	}

	#docs-sidebar .docs-sidebar-inner {
		position: static;
		gap: 0.75rem;
		max-height: none;
		padding: 1rem 1.5rem;
	}

	/* docs-nav.js collapses this on load; the cap keeps it usable once tapped
	   open, and keeps things sane if the script never runs. */
	#docs-sidebar .docs-nav-group {
		flex: 0 1 auto;
		max-height: 60vh;
	}

	#docs-sidebar .docs-nav {
		padding-block-end: 0.5rem;
	}

	body:has(#docs-sidebar) main {
		padding: 1.5rem 1.5rem 4rem;
	}
}

@media only screen and (max-width: 620px) {
	body:has(#docs-sidebar) main {
		padding: 1.25rem 1rem 3rem;
	}

	#docs-sidebar .docs-sidebar-inner {
		padding: 1rem;
	}

	.docs-breadcrumbs .docs-edit-link {
		margin-inline-start: 0;
	}
}
