.tag-item {padding:.6rem 0;border-bottom:1px solid rgba(0,0,0,.08);} 
.tag-item:last-child {border-bottom:none;} 
.tag-item .tag-row {display:flex;align-items:baseline;gap:1rem;flex-wrap:wrap;} 
.tag-item .title {margin:0;font-size:1.1rem;flex:1 1 auto;} 
.tag-item .tag-count {font-size:.85rem;opacity:.7;white-space:nowrap;} 

.archive-item {padding:.75rem 0;border-bottom:1px solid rgba(0,0,0,.08);}
.archive-item:last-child {border-bottom:none;}
.archive-row {display:grid;grid-template-columns:8rem 1fr;gap:1.5rem;align-items:baseline;}
.archive-date {font-size:.85rem;opacity:.65;white-space:nowrap;}
.archive-list .title {margin:0;font-size:1.05rem;}
.archive-desc {margin:.35rem 0 0;}
@media (max-width:600px){ .archive-row {grid-template-columns:1fr;gap:.25rem;} }

/* Title-only posts list (thinkingmachines.ai/blog-inspired) */
/* Extra specificity (.content ul.posts-list) to override theme's .content ul { list-style: disc } */
.content ul.posts-list {
	list-style: none;
	padding: 0;
	margin: 2rem 0 0;
}
.content ul.posts-list .posts-list-item {
	list-style: none;
	border-top: 1px solid rgba(0,0,0,.1);
	margin: 0;
}
.content ul.posts-list .posts-list-item::marker { content: ""; }
.content ul.posts-list .posts-list-item:last-child { border-bottom: 1px solid rgba(0,0,0,.1); }
.posts-list-link {
	display: grid;
	grid-template-columns: 13ch 1fr;
	gap: 1.5rem;
	align-items: baseline;
	padding: 1rem 0.25rem;
	border-bottom: none !important;
	text-decoration: none;
	color: inherit;
	transition: padding-left .15s ease;
}
.posts-list-link:hover, .posts-list-link:focus { padding-left: .75rem; }
.posts-list-date {
	font-size: .95rem;
	opacity: .7;
	letter-spacing: .02em;
	white-space: nowrap;
}
.posts-list-title {
	margin: 0;
	font-size: 1.15rem;
	font-weight: 600;
	line-height: 1.4;
	transition: color .15s ease;
}
.posts-list-link:hover .posts-list-title,
.posts-list-link:focus .posts-list-title { color: var(--color-primary, #dc143c); }
@media (max-width: 600px) {
	.posts-list-link { grid-template-columns: 1fr; gap: .2rem; padding: .85rem .25rem; }
	.posts-list-title { font-size: 1.05rem; }
	.posts-list-date { font-size: .85rem; }
}

/* Mermaid diagrams: make them larger and responsive */
.mermaid {
	display: block;
	margin: 1rem 0;
	overflow-x: auto;
	font-size: 18px;
}

.mermaid svg {
	width: 100% !important;
	height: auto !important;
	max-width: 100% !important;
	min-width: 560px; /* ensure readable baseline on desktop */
}

.mermaid svg[width][height],
svg[id^="m"][width][height][viewBox] {
	width: 100% !important;
	height: auto !important;
}

.mermaid text,
.mermaid .label {
	font-size: 18px !important;
}

/* Full-bleed wide variant for mermaid diagrams */
.mermaid.wide {
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

.mermaid.wide svg {
	width: 100vw !important;
	max-width: 100vw !important;
}

/* Larger scale variant when SVG appears visually small */
.mermaid.large {
	width: calc(100% * 1.35);
	max-width: none;
	overflow-x: auto;
}

.mermaid.large svg {
	transform: scale(1.35);
	transform-origin: top left;
}

/* KaTeX: base font-size override (main.css sets 1em; bump here for readability) */
.katex {
	font-size: 1.08em;
}

.katex-display > .katex {
	font-size: 1.08em;
}

/* Reduce space before headings (theme sets h2–h6 to 2em). */
h2, h3, h4, h5, h6 {
	margin-top: 1.2em;
	margin-block-start: 1.2em;
}

/* Post cover image — hero banner placed between the post header (title + meta)
   and the body/TOC. Any post bundle that includes a cover.{svg,png,jpg,webp}
   gets rendered here automatically by the single.html template. */
.post-cover {
	display: block;             /* theme defaults <figure> to inline-block */
	margin: 1.25rem auto 2rem auto;
	padding: 0;                 /* theme adds 2.5rem padding at ≥37.5em */
	max-width: var(--content-max-width, 800px);
	width: 100%;
}
/* Override the theme's @media (min-width: 37.5em) figure padding */
@media screen and (min-width: 37.5em) {
	.post-cover {
		padding-left: 0;
		padding-right: 0;
		padding-inline: 0;
	}
}
.post-cover img {
	display: block;
	width: 100%;
	height: auto;
	border: none;
	border-radius: 4px;
	max-width: 100%;
}

/* Left-align the post header (title + author + date).

   Coupling with TOC: see point 3 in the TOC design block below. Short
   centered titles read as a void to the right of the TOC; left-alignment
   makes the title's left edge land at the body paragraph's left edge,
   stable across title lengths.

   We let the theme's padding-left (.post-header 16px + .title/.meta 3px =
   19px) stand, since it lines up with the body's transform: translateX(20px).
   The 1px difference is invisible. */
.post-header,
.page .post-header {
	text-align: left;
}

/* ============================================================
   Diagram kit — HTML/CSS illustrations à la pi.website/distill.
   Use with the {{< diagram >}} shortcode + .diag-* primitives.
   ============================================================ */

/* Diagram-scoped color tokens. Override these in dark mode below. */
:root {
	--diag-node-bg: #ffffff;
	--diag-node-border: #d8d1c2;
	--diag-node-text: #232333;
	--diag-node-sub: #737373;
	--diag-node-primary-bg: #fdf2f3;
	--diag-node-primary-border: #dc143c;
	--diag-node-primary-text: #232333;
	--diag-node-muted-bg: #f4f0e8;
	--diag-node-muted-border: #d8d1c2;
	--diag-arrow: #a39a86;
	--diag-caption: #737373;
	--diag-bg: transparent;
}

/* Figure wrapper */
.diagram {
	display: block;
	margin: 1.75em auto;
	padding: 0;
	max-width: 100%;
}

.diagram--align-left  .diagram__body { justify-content: flex-start; margin-inline: 0; }
.diagram--align-center .diagram__body { justify-content: center; margin-inline: auto; }

/* Proportional scaling for over-wide diagrams. Diagrams stay within the text
   column. If the natural row width exceeds the available body width, a small
   script sets --diag-scale on the body, and `zoom` shrinks the inner content
   (including its layout box) so it fits without wrapping or scrolling. */
.diagram__body > .diag-row,
.diagram__body > .diag-col,
.diagram__body > .diag-stack {
	zoom: var(--diag-scale, 1);
}

.diagram__body {
	background: var(--diag-bg);
	border-radius: 8px;
	padding: 1.5em 1em;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.75em;
}

.diagram__caption {
	display: block;
	margin-top: 0.75em;
	text-align: center;
	font-size: 0.88rem;
	line-height: 1.5;
	color: var(--diag-caption);
	font-style: italic;
}

.diagram__label {
	font-weight: 600;
	font-style: normal;
	margin-right: 0.25em;
	color: var(--color-primary, #dc143c);
}

/* ---- Layout primitives ---- */
.diag-row {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: center;
	gap: 0.6em;
}

.diag-col {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.6em;
}

.diag-stack { /* tightly stacked column of nodes */
	display: flex;
	flex-direction: column;
	gap: 0.4em;
}

/* ---- Nodes ---- */
.diag-node {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 0.6em 1em;
	min-width: 7em;
	background: var(--diag-node-bg);
	color: var(--diag-node-text);
	border: 1.5px solid var(--diag-node-border);
	border-radius: 10px;
	font-size: 0.95rem;
	line-height: 1.35;
	box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}

.diag-node--primary {
	background: var(--diag-node-primary-bg);
	border-color: var(--diag-node-primary-border);
	color: var(--diag-node-primary-text);
}

.diag-node--muted {
	background: var(--diag-node-muted-bg);
	border-color: var(--diag-node-muted-border);
}

.diag-node--ghost {
	background: transparent;
	border-style: dashed;
}

/* Wall: an obstacle node — diagonal stripes, dashed border, taller. */
.diag-node--wall {
	background: repeating-linear-gradient(
		135deg,
		var(--diag-node-muted-bg),
		var(--diag-node-muted-bg) 6px,
		var(--diag-node-bg) 6px,
		var(--diag-node-bg) 10px
	);
	border-style: dashed;
	border-radius: 4px;
	border-color: var(--diag-node-border);
	min-height: 4.5em;
	min-width: 8em;
}

.diag-sub {
	display: block;
	font-size: 0.78rem;
	color: var(--diag-node-sub);
	margin-top: 0.2em;
}

/* ---- Arrows (CSS-only, no SVG needed for simple cases) ---- */
.diag-arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--diag-arrow);
	font-size: 1.4rem;
	line-height: 1;
	padding: 0 0.15em;
	user-select: none;
}

.diag-arrow--down { transform: rotate(90deg); }
.diag-arrow--up   { transform: rotate(-90deg); }

.diag-arrow-label {
	font-size: 0.75rem;
	color: var(--diag-node-sub);
	font-style: italic;
	padding: 0 0.25em;
}

/* ---- Responsive: stack horizontal rows on narrow screens ---- */
@media (max-width: 40em) {
	.diag-row {
		flex-direction: column;
	}
	.diag-row .diag-arrow {
		transform: rotate(90deg);
	}
	.diag-row .diag-arrow--down { transform: rotate(90deg); }
}

/* ---- Dark mode (the theme loads dark.css under prefers-color-scheme: dark) ---- */
@media (prefers-color-scheme: dark) {
	:root {
		--diag-node-bg: #2a2c33;
		--diag-node-border: #44464f;
		--diag-node-text: #eaeaea;
		--diag-node-sub: #aaaaaa;
		--diag-node-primary-bg: #2d3a32;
		--diag-node-primary-border: #50fa7b;
		--diag-node-primary-text: #eaeaea;
		--diag-node-muted-bg: #232428;
		--diag-node-muted-border: #3a3c44;
		--diag-arrow: #7a7c84;
		--diag-caption: #aaaaaa;
	}

	.diag-node { box-shadow: 0 1px 2px rgba(0,0,0,0.3); }
}

/* ============================================================
   TOC: fixed-width right-aligned sidebar.

   DESIGN HISTORY / WHY IT LOOKS THE WAY IT DOES
   ---------------------------------------------
   The theme ships a grid-based layout where the TOC is one
   column of `.post-container` and the article is the other.
   We replaced that with a *fixed-width sidebar* anchored to
   the post-container, for a few reasons that fought each
   other along the way:

   1. Cover-image race condition (was JS-based)
      The earlier implementation used `position: fixed` and a
      `<script>` in single.html that read
      `body.getBoundingClientRect().top` to align the TOC with
      the body's top. That measurement happens before the
      cover SVG's intrinsic dimensions are known to the
      browser, so on a fresh (uncached) cover the TOC ended up
      misaligned. We replaced JS with CSS by making the TOC
      `position: absolute; top: 0` inside a `position:
      relative` post-container — CSS pins the TOC to the
      post-container's top, which is *by definition* the
      body's top, and no measurement is needed. The inner
      `.toc` uses `position: sticky` for scroll-stick.

   2. Horizontal gap to body text
      Body content is shifted right by `transform:
      translateX(20px)` (theme rule). To get a small visual
      gap (~8px) between the TOC's right edge and the body's
      visible left edge, the wrapper's right edge sits 12px
      *into* the post-container's layout box, i.e.
      `right: calc(100% - 12px)`. Gap = 20 - 12 = 8px.

   3. Title alignment with body
      The post H1 used to be `text-align: center`. With a
      right-aligned TOC, a short centered title would float to
      the middle of the column and read as a huge void between
      the TOC's right edge and the title's left edge — even
      though the gap to the body paragraph (further down) was
      always 8px. Fixed by left-aligning `.post-header` so the
      title's left edge always lands at the body's left edge,
      stable across short and long titles.

   4. Wrapper width tradeoff
      Tried several variations:
        - shrink-to-fit cap 12rem  → long entries wrap
        - shrink-to-fit cap 14-16rem → felt "compressed" /
          inconsistent across posts (wrapper width varied by
          content)
        - fixed 14rem → every post gets the same column width,
          consistent post-to-post; short entries leave empty
          *page background* on the left of the text (which has
          no visible boundary and so reads cleanly).
      Settled on fixed 14rem sidebar.

   5. Generality
      All rules use `.page .X` selectors, so the layout
      applies uniformly to any single-page render (posts,
      about, etc.) — not About-specific. Vertical position
      will differ between posts (which have a cover pushing
      the TOC ~270px lower) and About (no cover, TOC starts
      right under the title), but horizontal layout is
      identical.

   Hugo's TableOfContents emits a wrapper <li> around the
   actual list (placeholder for the implicit H1); we flatten
   it so it doesn't add a phantom blank line at the top.
   ============================================================ */

/* Hidden by default — only revealed on wide viewports. */
.toc-wrapper {
	display: none;
}

@media screen and (min-width: 60em) {
	/* Theme's .post-container is a grid (auto + 1fr) for the old TOC
	   layout; collapse to block since our TOC is absolutely positioned
	   and shouldn't occupy a grid track. */
	.page .post-container {
		display: block;
	}
}

/* Only show the floating TOC when there is actually room beside the article.
   With a 14rem (224px) TOC, ~8px viewport-edge gutter, an 800px article column
   shifted +20px, and a 36px gap between TOC and body, the minimum viewport
   that fits all of it is roughly 1296px (81em). Below that, the TOC hides. */
@media screen and (min-width: 81em) {
	/* Anchor for the absolutely-positioned TOC (see point 1 above). */
	.page .post-container {
		position: relative;
	}

	.toc-wrapper {
		display: block;
		position: absolute;
		top: 0;
		/* Right edge sits 16px past the post-container's left edge, giving
		   a 36px visible gap to the body's translateX(20px)-shifted text.
		   See point 2 above. Knob for adjusting the gap:
		     calc(100% + 24px)  →  44px visible gap
		     calc(100% + 16px)  →  36px visible gap  (current)
		     calc(100% + 8px)   →  28px visible gap
		     calc(100% - 0px)   →  20px visible gap
		     calc(100% - 12px)  →   8px visible gap
		   Larger gaps may require bumping the @media breakpoint above so
		   the TOC doesn't run off the left edge at the narrowest screen. */
		right: calc(100% + 16px);
		/* Fixed sidebar width (point 4 above). Bumping this requires
		   bumping the breakpoint too: each +1rem of width needs roughly
		   +1em of breakpoint to keep the TOC from running off the left
		   edge of the viewport at the narrowest screen where it shows. */
		width: 14rem;
		height: 100%;     /* span the article so inner sticky has room */
		text-align: right;
	}

	/* Inner .toc is what actually sticks during scroll (point 1).
	   Stays at viewport top:1rem within the wrapper's height range. */
	.toc-wrapper > .toc {
		position: sticky;
		top: 1rem;
		max-height: calc(100vh - 2rem);
		overflow-y: auto;
		text-align: right;
		max-width: none;
		width: auto;
		left: auto;
		right: auto;
		margin: 0;
		padding: 0;
	}

	/* Reset the theme's .page .toc absolute positioning that would
	   otherwise fight our sticky rule. */
	.page .toc {
		position: sticky;
		text-align: right;
		max-width: none;
		width: auto;
		top: 1rem;
		left: auto;
		right: auto;
		margin: 0;
		padding: 0;
	}

	/* Flatten Hugo's wrapper <li> — the outermost ul contains a single empty
	   li that wraps the actual list. Strip its markers, padding, and margin
	   so it contributes no vertical space. */
	.toc-wrapper .toc > nav > ul,
	.toc-wrapper .toc > nav > ul > li,
	.toc-wrapper .toc > nav > ul > li > ul {
		list-style: none;
		margin: 0;
		padding: 0;
	}

	/* Top-level visible items (H2). */
	.toc-wrapper .toc > nav > ul > li > ul > li {
		margin: 0.3rem 0;
		list-style: none;
	}

	/* Nested items (H3+): tighter spacing, smaller, dimmer. */
	.toc-wrapper .toc > nav > ul > li > ul > li ul {
		list-style: none;
		margin: 0.1rem 0 0 0;
		padding: 0;
	}
	.toc-wrapper .toc > nav > ul > li > ul > li ul li {
		margin: 0.15rem 0;
		list-style: none;
	}
	.toc-wrapper .toc > nav > ul > li > ul > li ul a {
		font-size: 0.72rem;
		opacity: 0.8;
	}

	/* Link styles: subtle muted text, hover is just a color shift (no underline). */
	.toc-wrapper .toc a {
		color: var(--color-text-muted, #737373);
		font-size: 0.8rem;
		line-height: 1.45;
		border-bottom: none;
		text-decoration: none;
		display: inline-block;
		padding: 0.05rem 0;
		transition: color 0.15s ease;
	}
	.toc-wrapper .toc a:hover,
	.toc-wrapper .toc a:focus {
		color: var(--color-text, #232333);
		border-bottom: none;
	}
}

/* Images dropped inside a diagram body should not get the global img border. */
.diagram__body img {
	border: none;
	border-radius: 4px;
}

/* Pagination — Prev/Next row under paginated section lists.
   The theme partial emits an empty <span> on whichever side has no
   target, so flexbox with space-between keeps "Next →" anchored right
   on page 1 and "← Prev" anchored left on the last page. */
.pagination,
.content ul.pagination {
	list-style: none;
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 1rem;
	padding: 0;
	margin: 2.5rem 0 1rem;
	border-top: 1px solid rgba(0,0,0,.08);
	padding-top: 1.25rem;
}
.pagination .page-item {
	display: inline-flex;
	min-width: 0;
}
.pagination .page-prev { margin-right: auto; }
.pagination .page-next { margin-left: auto; }
.pagination .page-link {
	display: inline-block;
	padding: .45rem .9rem;
	border: 1px solid rgba(0,0,0,.15);
	border-radius: var(--border-radius, 5px);
	color: inherit;
	text-decoration: none;
	font-size: .95rem;
	line-height: 1.2;
	transition: border-color .15s ease, color .15s ease;
}
.pagination .page-link:hover,
.pagination .page-link:focus {
	border-color: var(--color-primary, #dc143c);
	color: var(--color-primary, #dc143c);
}
