/* ==========================================================================
   andyfreeland.com

   Obsidian Publish's default theme, with a different typeface, a larger
   type size, and a greyscale palette on a darker ground.

   The default vertical rhythm is kept as-is, with one exception. Obsidian's
   heading margins are em-based and scale correctly, but its paragraph and
   rule margins are fixed pixels (16px and 32px). At the default 16px body
   those are 0.67 and 1.33 line-heights; at 21px they fall to 0.51 and 1.02,
   because the line grew and the margin didn't. The two rules at the bottom
   restore the default RATIOS at this size — not a new design, the same
   proportions the default has. Line height stays at the default 1.5.

   Graph view and sidebars are Publish *settings*. Turn them off there.
   ========================================================================== */


/* --------------------------------------------------------------------------
   Type
   To go back to a sans-serif, change --font-read to var(--font-sans).
   -------------------------------------------------------------------------- */

body {
	--font-read:
		"Iowan Old Style", "Palatino Linotype", Palatino, Charter,
		Georgia, "Times New Roman", serif;
	--font-sans:
		-apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;

	--font-text-theme: var(--font-read);
	--font-interface-theme: var(--font-sans);

	/* 21px puts the default column at 67 characters / 2.57 alphabets — the
	   centre of Butterick's 45–90 range and Bringhurst's 2–3 alphabet test.
	   Measure is set by type size, not by width, so the layout stays default. */
	--font-text-size: 21px;

	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}


/* On a phone the column is ~327px, so 21px yields only 31 characters a line —
   well under Butterick's 45 minimum. No size actually reaches 45 at this
   width (16px gets to 41), so this is the readable compromise at 36. Headings
   are in em and follow automatically. Size only; no layout changes. */
@media (max-width: 46em) {
	body {
		--font-text-size: 18px;
	}
}


/* --------------------------------------------------------------------------
   Palette
   Obsidian's default dark theme reads well because it LIFTS the background
   (#dadada on #1e1e1e) rather than dimming the text. This keeps that
   approach on a slightly deeper ground. Set on both theme classes so light
   mode can't happen.
   -------------------------------------------------------------------------- */

body,
body.theme-light,
body.theme-dark {
	/* Sampled from sive.rs, which paints the entire page in three values:
	   #0a0a0a ground, #eeeeee for ALL text — body, headings and bold alike —
	   and #ccccff for links, underline included. The greys below have no
	   equivalent there; they're carried over for the muted roles this site
	   has and sive.rs doesn't (nav rest state, asides, unresolved links). */
	--mono-bg:     #0a0a0a;
	--mono-rule:   #2a2a2a;
	--mono-faint:  #666666;
	--mono-aside:  #aaaaaa;
	--mono-nav:    #888888;   /* nav rest state, one step down from aside */
	--mono-body:   #eeeeee;
	/* Not pure white any more — sive.rs sets headings to the same value as
	   body text, so hierarchy there is carried by size alone. */
	--mono-bright: #eeeeee;

	/* Links carry a hue so they don't fight body text for value.
	   Change these two to restyle every link on the site.
	   This sits meaningfully dimmer than body text (1.33:1), which is what
	   makes a link read as a link — the underline reinforces it rather than
	   carrying it alone. */
	--link:       #ccccff;
	--link-hover: #ffffff;

	--background-primary: var(--mono-bg);
	--background-primary-alt: var(--mono-bg);
	--background-secondary: var(--mono-bg);
	--background-secondary-alt: var(--mono-bg);
	--background-modifier-border: var(--mono-rule);
	--background-modifier-hover: var(--mono-rule);

	--text-normal: var(--mono-body);
	--text-muted: var(--mono-aside);
	--text-faint: var(--mono-faint);
	--text-accent: var(--link);
	--text-accent-hover: var(--link-hover);
	--link-color: var(--link);
	--link-color-hover: var(--link-hover);
	--text-on-accent: var(--mono-bg);
	--text-title-h1: var(--mono-bright);
	--text-title-h2: var(--mono-bright);
	--text-title-h3: var(--mono-bright);
	--text-bold: var(--mono-bright);
	--text-selection: rgba(204, 204, 255, 0.25);
	--text-highlight-bg: #33334d;
	--text-highlight-bg-active: #444466;

	--interactive-accent: var(--link);
	--hr-color: var(--mono-rule);
	--blockquote-border-color: var(--mono-rule);
	--code-background: #222222;
	--code-normal: var(--mono-aside);

	color-scheme: dark;
}


/* --------------------------------------------------------------------------
   Hierarchy — size and colour only, no spacing

   Modular scale, uniform 1.2 ratio, in em so the default em-based margins
   scale with each heading automatically: 36.3 / 30.2 / 25.2 / 21 body.

   A 1.333 ratio separated h1 from h2 well but left no room for a distinct h3
   above body size — h3 sat either at body size, reading as a caption, or only
   1.11 from h2, which is the same "one size used twice" problem. Even 1.2
   steps give four levels that each read as their own.
   -------------------------------------------------------------------------- */

.published-container .markdown-rendered h1,
.published-container .markdown-rendered h2,
.published-container .markdown-rendered h3 {
	color: var(--mono-bright);
	/* Iowan Old Style renders three weights and no more: 100-500 all resolve
	   to Roman, 600-700 both resolve to the real Bold face, 800-900 add
	   synthetic emboldening on top. So 500 would be a no-op and 600 is the
	   only step up available — it is a genuine face, not a smeared fake. */
	font-weight: 600;
	letter-spacing: -0.012em;
	text-wrap: balance;
	border-bottom: none;
	padding-bottom: 0;
}

.published-container .markdown-rendered h1 { font-size: 1.728em; }
.published-container .markdown-rendered h2 { font-size: 1.44em; }
.published-container .markdown-rendered h3 { font-size: 1.2em; }

.published-container .markdown-rendered p,
.published-container .markdown-rendered li {
	color: var(--mono-body);
	/* Line breaking, not spacing — avoids single-word last lines. */
	text-wrap: pretty;
}

.published-container .markdown-rendered strong,
.published-container .markdown-rendered b {
	color: var(--mono-bright);
	font-weight: 600;
}

.published-container .markdown-rendered a strong,
.published-container .markdown-rendered a b {
	color: inherit;
}

.published-container .markdown-rendered blockquote {
	color: var(--mono-aside);
	font-style: italic;
}

.published-container .markdown-rendered mark {
	background-color: var(--text-highlight-bg);
	color: var(--mono-bright);
}

/* Oldstyle figures sit on the baseline like lowercase — "$2,500" reads as
   prose rather than as data. */
.published-container .markdown-rendered {
	font-variant-numeric: oldstyle-num;
}


/* --------------------------------------------------------------------------
   Links
   -------------------------------------------------------------------------- */

/* :visited must be named explicitly. Without it the browser falls back to its
   own visited colour — a dark purple (#551A8B) in Safari — which is why links
   already tapped on a phone render darker than unvisited ones. Browsers only
   allow a few properties on :visited for privacy reasons; colour is one.

   Scoped to .markdown-rendered, NOT .published-container: the latter wraps the
   whole site including the sidebar, so a bare `a` under it outranks the
   wordmark and nav rules and turns the sidebar into body links. */
.published-container .markdown-rendered a,
.published-container .markdown-rendered a:visited,
.published-container .internal-link,
.published-container .internal-link:visited,
.published-container .external-link,
.published-container .external-link:visited {
	color: var(--link);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-decoration-color: var(--link);
	text-underline-offset: 0.16em;
	transition: color 120ms ease, text-decoration-color 120ms ease;
}

.published-container .markdown-rendered a:hover,
.published-container .internal-link:hover,
.published-container .external-link:hover {
	color: var(--link-hover);
	text-decoration-color: var(--link-hover);
}

/* No arrow glyph after external links. The padding-right closes the gap the
   icon leaves behind. That and the padding-bottom under headings (which goes
   with removing their default underline) are the only spacing rules in this
   file — both remove space rather than set it. */
.published-container .external-link,
.published-container a.external-link {
	background-image: none;
	padding-right: 0;
}

.published-container .external-link-icon {
	display: none;
}

/* Publish appends a "Copy link" control to every heading on hover. It is a
   .clickable-icon, not the .copy-heading-link class named in app.css — and a
   bare .clickable-icon rule loses to Publish's own more specific one, so this
   is scoped to the heading. Measured on the live page. */
.published-container .publish-article-heading .clickable-icon {
	display: none;
}

/* Links to unpublished notes — never ship one of these live. */
.published-container .internal-link.is-unresolved {
	color: var(--mono-faint);
	text-decoration-style: dotted;
}

/* The wordmark is identity, not an action — keep it out of the link system. */
.site-header-text,
.site-header-text:visited,
.site-body-left-column-site-name,
.site-body-left-column-site-name:visited {
	color: var(--mono-bright);
	text-decoration: none;
	font-family: var(--font-read);
}

/* Centre the name under the portrait in the desktop sidebar. This element
   only exists in the left column, which Publish renders on desktop widths
   only, so the mobile header is unaffected and no media query is needed. */
.site-body-left-column-site-name {
	text-align: center;
	/* Left at Roman: the wordmark is identity, not hierarchy, and it doesn't
	   need to compete with the headings for weight. */
	font-weight: 400;
	/* Publish ships this with padding: 4px 32px 32px 0 — asymmetric horizontal
	   padding, so centred text lands 16px left of the portrait above it.
	   Zero the sides. The 32px bottom stacked with .nav-view-outer's 10px top
	   for a 49px gap against 10px between nav rows — a 4.9x step. 12px brings
	   it to ~29px, about 3x, which reads as a group break instead of a void. */
	padding-left: 0;
	padding-right: 0;
	padding-bottom: 12px;
}


/* --------------------------------------------------------------------------
   Sidebar navigation

   Publish builds the tree from .tree-item-*, not .nav-file-title.
   Three states: rest grey, white on hover, purple on the current page.
   -------------------------------------------------------------------------- */

.nav-view,
.nav-view .tree-item-self,
.nav-view .tree-item-inner,
.search-bar {
	font-family: var(--font-read);
	font-size: 0.95rem;
}

/* .tree-item-inner carries its own colour from app.css, so setting the row
   alone does nothing — both have to be named, in all three states. */
.nav-view .tree-item-self,
.nav-view .tree-item-self:visited,
.nav-view .tree-item-inner,
.nav-view .tree-item-inner:visited {
	color: var(--mono-nav);
	transition: color 120ms ease;
}

.nav-view .tree-item-self:hover,
.nav-view .tree-item-self:hover .tree-item-inner {
	color: var(--mono-bright);
}

.nav-view .tree-item-self.mod-active,
.nav-view .tree-item-self.mod-active .tree-item-inner {
	color: var(--link);
}

/* Centred. The row is flex, so justify-content does the work — and every
   horizontal offset has to go or the centre drifts: Publish's negative start
   margin, the row padding, and the children indent. */
.nav-view .tree-item-self {
	justify-content: center;
	text-align: center;
	padding-left: 0;
	padding-right: 0;
	margin-inline-start: 0;
}

.nav-view .tree-item-children {
	padding-left: 0;
}

/* .nav-view-outer scrolls, reserving an 8px scrollbar gutter — which made
   centred labels sit 4px left of the portrait above them. The nav is a handful
   of links and never scrolls, so reclaim the gutter. */
.nav-view-outer {
	scrollbar-width: none;
}

.nav-view-outer::-webkit-scrollbar {
	display: none;
}

.nav-view .collapse-icon {
	color: var(--mono-faint);
}

.search-bar {
	background: #222222;
	border-color: var(--mono-rule);
	color: var(--mono-body);
}

/* The site is dark-only, so the theme toggle does nothing. */
.site-body-left-column-site-theme-toggle {
	display: none;
}

.site-header-text:hover,
.site-body-left-column-site-name:hover {
	color: var(--mono-aside);
}


/* --------------------------------------------------------------------------
   Kept from your original file
   -------------------------------------------------------------------------- */

.site-footer,
.clickable-icon {
	display: none;
}


/* --------------------------------------------------------------------------
   Scale correction
   Obsidian's paragraph (16px) and rule (32px) margins are fixed pixels, so
   they shrink relative to the line as type size goes up. These two rules
   restore the default's own proportions at 21px:
     paragraph  1em = 21px = 0.67 lines  (default: 16/24 = 0.67)
     rule       2em = 42px = 1.33 lines  (default: 32/24 = 1.33)
   Nothing else here sets spacing.
   -------------------------------------------------------------------------- */

.published-container .markdown-rendered p,
.published-container .markdown-rendered ul,
.published-container .markdown-rendered ol {
	margin-top: 1em;
	margin-bottom: 1em;
}

.published-container .markdown-rendered hr {
	margin-top: 2em;
	margin-bottom: 2em;
}


/* --------------------------------------------------------------------------
   Callouts

   Obsidian consumes --callout-color as comma-separated RGB channels, never a
   hex — it is used as rgba(var(--callout-color), 0.1) for the fill and
   rgb(var(--callout-color)) for the title, so a hex value breaks both.

   Every callout gets the same neutral treatment. A note here is an aside, not
   a status badge, so nothing is colour-coded. It reads as a filled panel with
   a hairline edge, which keeps it distinct from a blockquote (left rule,
   italic, no fill) at a glance.
   -------------------------------------------------------------------------- */

.callout {
	/* Neutral channels — anything left to Obsidian's own rules stays greyscale. */
	--callout-color: 220, 220, 220;
	/* No border. At this size the fill alone reads as a panel, and any edge
	   bright enough to see is brighter than anything else on the page. */
	--callout-border-width: 0px;
	--callout-border-opacity: 0;
	--callout-radius: 3px;
	--callout-blend-mode: normal;
	/* Default padding is lopsided (24px on the left) to clear the icon, which
	   is hidden below — even it up. */
	--callout-padding: 1em 1.15em;
	--callout-title-padding: 0;
	--callout-title-size: 1em;
	--callout-title-weight: 400;

	/* Slightly lifted now that nothing outlines the box. */
	background-color: rgba(255, 255, 255, 0.05);
	border: none;
	font-size: 0.95em;
}

.callout-title {
	color: var(--mono-bright);
	font-family: var(--font-read);
	font-weight: 400;
	letter-spacing: 0.01em;
	margin-bottom: 0.35em;
}

/* Scoped through .published-container .markdown-rendered so this outweighs
   the body-copy rule, which is 0,3,0 and would otherwise win. */
.callout-content,
.published-container .markdown-rendered .callout-content,
.published-container .markdown-rendered .callout-content p,
.published-container .markdown-rendered .callout-content li {
	color: var(--mono-aside);
}

.published-container .markdown-rendered .callout-content p:last-child {
	margin-bottom: 0;
}

/* Icons inherit the title colour. Publish's renderer rewrites any inline SVG
   with fill/stroke set to currentColor, so nothing here needs a colour. */
.callout-icon {
	display: flex;
	align-items: center;
	color: inherit;
	margin-right: 0.5em;
}

.callout-icon svg {
	width: 1em;
	height: 1em;
}


/* --------------------------------------------------------------------------
   [!next] — the forward step

   Publish reads --callout-icon from CSS at render time (app.js: it checks
   data-callout-icon, then falls back to getCssPropertyValue). The value may
   be a Lucide name or an inline SVG in single quotes. Publish only bundles
   ~15 Lucide icons and no arrow among them, so this uses an inline SVG —
   guaranteed to render and self-contained, nothing fetched.

   Each path carries its own fill="none": the renderer forces fill to
   currentColor on the root element, which would otherwise flood these open
   paths into solid shapes.
   -------------------------------------------------------------------------- */

.callout[data-callout="next"] {
	--callout-icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 12h15" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round"/><path d="m12.5 5.5 7 6.5-7 6.5" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/></svg>';
}

/* A title-only callout shouldn't carry a trailing gap. */
.callout-title:last-child {
	margin-bottom: 0;
}


/* --------------------------------------------------------------------------
   Media

   Video embeds run the full width of the column. Publish builds these as
   <iframe class="external-embed"> sized by width/height attributes, so both
   the width and a 16:9 ratio have to be set here or the player sits short
   of the measure with dead space beside it.

   The image rules were lost in an earlier rewrite of this file — without a
   max-width an Excalidraw export wider than the column overflows it.
   -------------------------------------------------------------------------- */

.published-container .markdown-rendered iframe,
.published-container .external-embed {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	border: none;
	border-radius: 3px;
	margin: 1.5em 0;
}

/* img only — NOT svg. Excalidraw exports embed as <img src="...svg">, so the
   svg selector was never needed here, and it also matched the inline SVG
   inside .callout-icon: the 1.5em margin inflated the icon box to 80px and
   dropped the arrow below its own title line. */
.published-container .markdown-rendered img {
	display: block;
	max-width: 100%;
	height: auto;
	margin: 1.5em auto;
	background: transparent;
}

/* Icons are inline furniture, not figures — no layout of their own. */
.callout-icon svg {
	display: inline-block;
	width: 1em;
	height: 1em;
	margin: 0;
	flex: none;
}

/* The row is flex; without this the icon box stretches to the row height and
   centring places the glyph away from the text it belongs to. */
.callout-title {
	align-items: baseline;
}

.callout-icon {
	align-self: baseline;
}

/* Baseline alignment gets the icon box into the right neighbourhood but not
   onto the right line. An SVG has no text baseline, so the browser uses its
   bottom margin edge — which parks a 1em box entirely above the baseline,
   and the arrow, drawn on the centreline of its 24x24 viewBox, ends up half
   a box above it. Dropping it back down lands it on the lowercase midline.
   The pure x-height maths says 0.26em; that reads a touch low against a
   serif this open, so this is tuned by eye instead. */
.callout-icon svg {
	transform: translateY(0.2em);
}


/* --------------------------------------------------------------------------
   11. Multi-column layout

   Markdown syntax:
   > [!cols]
   >> [!col]
   >> Column one
   >> [!col]
   >> Column two

   Optional alignment:
   >> [!col|left] / >> [!col|center] / >> [!col|right]
   -------------------------------------------------------------------------- */

.published-container .markdown-rendered .callout[data-callout="cols"] {
	border: none;
	background: transparent;
	padding: 0;
	margin: 0;
}

.published-container .markdown-rendered .callout[data-callout="cols"] .callout-title {
	display: none;
}

.published-container .markdown-rendered .callout[data-callout="cols"] .callout-content {
	display: flex;
	flex-wrap: wrap;
	gap: 1.5em;
	padding: 0;
	margin: 0;
}

/* Column types — remove callout styling, set alignment */

/* All column variants */
.published-container .markdown-rendered .callout[data-callout="col"],
.published-container .markdown-rendered .callout[data-callout="col-left"],
.published-container .markdown-rendered .callout[data-callout="col-center"],
.published-container .markdown-rendered .callout[data-callout="col-right"],
.published-container .markdown-rendered .callout[data-callout="col-bg"],
.published-container .markdown-rendered .callout[data-callout="col-bg-left"],
.published-container .markdown-rendered .callout[data-callout="col-bg-center"],
.published-container .markdown-rendered .callout[data-callout="col-bg-right"] {
	flex: 1 1 auto;
	min-width: 0;
}

/* No background variants */
.published-container .markdown-rendered .callout[data-callout="col"],
.published-container .markdown-rendered .callout[data-callout="col-left"],
.published-container .markdown-rendered .callout[data-callout="col-center"],
.published-container .markdown-rendered .callout[data-callout="col-right"] {
	border: none;
	background: transparent;
	padding: 0;
	margin: 0;
}

.published-container .markdown-rendered .callout[data-callout="col"] .callout-title,
.published-container .markdown-rendered .callout[data-callout="col-left"] .callout-title,
.published-container .markdown-rendered .callout[data-callout="col-center"] .callout-title,
.published-container .markdown-rendered .callout[data-callout="col-right"] .callout-title {
	display: none;
}

.published-container .markdown-rendered .callout[data-callout="col"] .callout-content,
.published-container .markdown-rendered .callout[data-callout="col-left"] .callout-content,
.published-container .markdown-rendered .callout[data-callout="col-center"] .callout-content,
.published-container .markdown-rendered .callout[data-callout="col-right"] .callout-content {
	padding: 0;
	margin: 0;
}

/* Background variants — keep callout styling */
.published-container .markdown-rendered .callout[data-callout="col-bg"],
.published-container .markdown-rendered .callout[data-callout="col-bg-left"],
.published-container .markdown-rendered .callout[data-callout="col-bg-center"],
.published-container .markdown-rendered .callout[data-callout="col-bg-right"] {
	border: none;
	padding: 1em;
	margin: 0;
	background-color: rgba(255, 255, 255, 0.05);
}

.published-container .markdown-rendered .callout[data-callout="col-bg"] .callout-title,
.published-container .markdown-rendered .callout[data-callout="col-bg-left"] .callout-title,
.published-container .markdown-rendered .callout[data-callout="col-bg-center"] .callout-title,
.published-container .markdown-rendered .callout[data-callout="col-bg-right"] .callout-title {
	display: none;
}

/* Alignment using flexbox justify-content */
.published-container .markdown-rendered .callout[data-callout="col-left"],
.published-container .markdown-rendered .callout[data-callout="col-bg-left"] {
	display: flex;
	justify-content: flex-start;
}

.published-container .markdown-rendered .callout[data-callout="col-center"],
.published-container .markdown-rendered .callout[data-callout="col-bg-center"] {
	display: flex;
	justify-content: center;
}

.published-container .markdown-rendered .callout[data-callout="col-right"],
.published-container .markdown-rendered .callout[data-callout="col-bg-right"] {
	display: flex;
	justify-content: flex-end;
}

/* Mobile-stackable columns — default to side-by-side, stack on narrow screens */
.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] {
	border: none;
	background: transparent;
	padding: 0;
	margin: 0;
}

.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout-title {
	display: none;
}

.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout-content {
	display: flex;
	flex-wrap: wrap;
	gap: 1.5em;
	padding: 0;
	margin: 0;
}

@media (max-width: 46em) {
	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout-content {
		flex-direction: column;
		gap: 1em;
	}

	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout[data-callout="col"],
	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout[data-callout="col-left"],
	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout[data-callout="col-center"],
	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout[data-callout="col-right"],
	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout[data-callout="col-bg"],
	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout[data-callout="col-bg-left"],
	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout[data-callout="col-bg-center"],
	.published-container .markdown-rendered .callout[data-callout="cols-mobile-stack"] .callout[data-callout="col-bg-right"] {
		flex: 1 1 100%;
		justify-content: center;
	}
}

