/*
 * site.css — the blog's own styles, authored against Web Awesome tokens.
 *
 * This file replaces wisselblog.css, of which only about 1.1KB of 78KB was
 * genuine site identity; the rest was Bootstrap overrides and an unused Font
 * Awesome glyph set.
 */

/* ---------------------------------------------------------------------------
 * Site header
 *
 * A flex row that wraps, rather than a navbar with a JS-driven drawer. At phone
 * widths the brand stays on the first line and the links wrap beneath it, so
 * there is no hidden state, no toggle and no script.
 * ------------------------------------------------------------------------- */
.site-header {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wa-space-m, 1rem);
	padding: var(--wa-space-s, .5rem) var(--wa-space-l, 1.5rem);
	background: var(--wa-color-neutral-fill-quiet);
	border-bottom: 1px solid var(--wa-color-surface-border);
}

.site-brand {
	font-weight: 700;
	font-size: 1.125rem;
	text-decoration: none;
	color: var(--wa-color-text-normal);
}

.site-nav {
	flex: 1 1 auto;
}

.site-nav ul {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wa-space-xs, .25rem) var(--wa-space-m, 1rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-nav a {
	text-decoration: none;
	color: var(--wa-color-text-quiet);
	padding: var(--wa-space-2xs, .125rem) 0;
}

.site-nav a:hover {
	color: var(--wa-color-text-normal);
}

/* /why aria-current rather than a class: the renderer already knows which
 * section is active, and aria-current states it to assistive technology as well
 * as to the stylesheet. One attribute, two jobs. */
.site-nav a[aria-current="page"] {
	color: var(--wa-color-brand-on-quiet);
	font-weight: 600;
	box-shadow: inset 0 -2px 0 var(--wa-color-brand-border-loud);
}

.site-search input[type="search"] {
	font: inherit;
	padding: var(--wa-space-2xs, .25rem) var(--wa-space-s, .5rem);
	border: 1px solid var(--wa-color-surface-border);
	border-radius: var(--wa-border-radius-m, .25rem);
	background: var(--wa-color-surface-default);
	color: var(--wa-color-text-normal);
	min-width: 8rem;
}

/* ---------------------------------------------------------------------------
 * Layout
 * ------------------------------------------------------------------------- */
main { padding-inline: var(--wa-space-l, 1.5rem); }
main > * { max-width: 62rem; }

/* /why not a Bootstrap grid: the only multi-column rows left after the navbar
 * and sidebar went were the footer and the downloads table. Two auto-fitting
 * grids replace twelve span classes. */
.footer-columns {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
	gap: var(--wa-space-l, 1.5rem);
}

/* ---------------------------------------------------------------------------
 * The hero, and the site's own identity
 *
 * The old .hero-unit carried two background photographs (stw1.jpg / stw2.jpg)
 * behind the title. They are kept: they are the most recognisable thing about
 * the site. What goes is Bootstrap's 60px padding and 4px radius.
 * ------------------------------------------------------------------------- */
.site-hero {
	background: var(--wa-color-neutral-fill-quiet) center / cover no-repeat;
	background-blend-mode: normal;
	border-radius: var(--wa-border-radius-l, .5rem);
	padding: var(--wa-space-xl, 2rem);
	margin-block: var(--wa-space-l, 1.5rem);
}
.site-hero h1, .site-hero h2 { margin: 0; }
.site-hero p { margin: var(--wa-space-s, .5rem) 0 0; font-size: 1.125rem; }

/* /why aspect-ratio plus object-fit: hero covers are authored at two sizes --
 * 1792x1024 for 88% of posts and 1536x1024 for the rest. A fixed ratio with
 * object-fit: cover crops both consistently; without object-fit the default
 * `fill` would stretch roughly 170 of them. */
.hero-image {
	width: 100%;
	aspect-ratio: 7 / 4;
	object-fit: cover;
	border-radius: var(--wa-border-radius-l, .5rem);
}

/* ---------------------------------------------------------------------------
 * Entry cards -- the listing unit on index, year, month and category pages.
 *
 * article stays an article: wrapping it in wa-card would have buried the
 * semantics a post listing depends on, so the card look is applied directly.
 * The shadow is wisselblog.css's own .well-raised, kept verbatim: it is on
 * every content box on the site and is the one purely decorative decision
 * worth carrying over.
 * ------------------------------------------------------------------------- */
.entry-card {
	display: block;
	background: var(--wa-color-surface-default);
	border: 1px solid var(--wa-color-surface-border);
	border-radius: var(--wa-border-radius-l, .5rem);
	padding: var(--wa-space-l, 1.5rem);
	margin-block: var(--wa-space-l, 1.5rem);
	box-shadow: 0 2px 4px rgb(0 0 0 / .12), 0 4px 8px rgb(0 0 0 / .06);
}

/* ---------------------------------------------------------------------------
 * Post furniture
 * ------------------------------------------------------------------------- */
.entry-tags { display: flex; flex-wrap: wrap; gap: var(--wa-space-xs, .5rem); margin-block: var(--wa-space-s, .5rem); }
.entry-tag {
	font-size: .8125rem;
	padding: .125rem .5rem;
	border-radius: var(--wa-border-radius-pill, 999px);
	background: var(--wa-color-brand-fill-quiet);
	color: var(--wa-color-brand-on-quiet);
	text-decoration: none;
}
.entry-tag-legacy { background: var(--wa-color-neutral-fill-quiet); color: var(--wa-color-neutral-on-quiet); }

.entry-nav {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: var(--wa-space-m, 1rem);
	margin-block: var(--wa-space-l, 1.5rem);
}
.entry-nav a { text-decoration: none; }
.entry-nav-up { color: var(--wa-color-text-quiet); }

.meta-sep { color: var(--wa-color-text-quiet); margin-inline: .35rem; }
.gravatarimg { float: right; width: 88px; height: 88px; border-radius: var(--wa-border-radius-m, .25rem); margin-inline-start: var(--wa-space-m, 1rem); }
#commentList { list-style: none; padding: 0; }
#commentList > li { border-bottom: 1px solid var(--wa-color-surface-border); padding-block: var(--wa-space-m, 1rem); }
#commentList > li::after { content: ""; display: block; clear: both; }

.series-list li[aria-current] { font-weight: 700; }

/* ---------------------------------------------------------------------------
 * Sidebar modules
 * ------------------------------------------------------------------------- */
.sidebar-module { margin-block-end: var(--wa-space-l, 1.5rem); display: block; }
.sidebar-list { list-style: none; margin: 0; padding: 0; max-height: 22rem; overflow-y: auto; }
.sidebar-list li { display: flex; justify-content: space-between; gap: var(--wa-space-s, .5rem); padding-block: .125rem; }
.sidebar-list li[aria-current] a { font-weight: 700; }
.sidebar-count { color: var(--wa-color-text-quiet); font-size: .8125rem; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
 * Content
 *
 * /why blockquote keeps a left rule: it is the one piece of wisselblog.css's
 * prose styling that carries meaning rather than decoration.
 * ------------------------------------------------------------------------- */
blockquote { border-inline-start: 4px solid var(--wa-color-surface-border); margin-inline-start: 0; padding-inline-start: var(--wa-space-m, 1rem); }
main img { max-width: 100%; height: auto; }
main table { width: 100%; border-collapse: collapse; }

/* /why this rule exists at all: inline code was styled only by
 * blogcodedisplay.css, which script_core loads ONLY when legacy GeSHi markup is
 * present. Every modern post therefore rendered inline code unstyled. */
:not(pre) > code, kbd {
	font-family: var(--wa-font-family-code, ui-monospace, monospace);
	font-size: .875em;
	padding: .1em .35em;
	border-radius: var(--wa-border-radius-s, .1875rem);
	background: var(--wa-color-neutral-fill-quiet);
}

/* ---------------------------------------------------------------------------
 * The last of the twelve-column grid
 *
 * Only the 404 page, the imprint and the cycling category still laid content
 * out in columns. auto-fit means they collapse to one column on narrow screens
 * without a single media query -- responsive.css needed seven.
 * ------------------------------------------------------------------------- */
.grid-row {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
	gap: var(--wa-space-l, 1.5rem);
	align-items: start;
}
.grid-row:has(> .grid-wide + .grid-narrow),
.grid-row:has(> .grid-narrow + .grid-wide) { grid-template-columns: 2fr 1fr; }
@media (max-width: 48rem) {
	.grid-row:has(> .grid-wide) { grid-template-columns: 1fr; }
}
.align-end { justify-self: end; text-align: end; }

/* ---------------------------------------------------------------------------
 * The two banner sizes
 *
 * /why IDs rather than classes: the renderer emits id="main" on index-style
 * pages and id="mainsmall" on entries, and that is the only signal in the markup
 * for which banner a page wants. These were ID rules in main.css too, which is
 * why they outranked .site-hero and flattened the banner to 37px until main.css
 * was retired.
 *
 * The large banner puts the title at the foot of the image rather than pushing
 * it down with 250px of padding, which is what it was doing before.
 * ------------------------------------------------------------------------- */
#main.site-hero {
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	min-height: 20rem;
	color: #fff;
	text-shadow: 0 1px 3px rgb(0 0 0 / .6);
}
#main.site-hero h1 { font-size: clamp(2rem, 5vw, 3rem); }

/* /why a scrim: both banner images are photographs with light and dark regions
 * in the same frame, so no single text colour is legible across them. A dark
 * gradient over the image gives the text a consistent ground to sit on. */
#mainsmall.site-hero, #main.site-hero {
	background-image:
		linear-gradient(to right, rgb(0 0 0 / .72) 0%, rgb(0 0 0 / .45) 60%, rgb(0 0 0 / .25) 100%),
		var(--site-hero-photo);
	color: #fff;
}
#main.site-hero    { --site-hero-photo: url(/blog/img/stw1.jpg); }
#mainsmall.site-hero { --site-hero-photo: url(/blog/img/stw2.jpg); }

#mainsmall.site-hero {
	display: flex;
	align-items: baseline;
	gap: var(--wa-space-m, 1rem);
	min-height: 0;
	padding: var(--wa-space-s, .75rem) var(--wa-space-l, 1.5rem);
}
#mainsmall.site-hero h2 { font-size: 1.25rem; }
#mainsmall.site-hero p { font-size: .875rem; margin: 0; color: rgb(255 255 255 / .85); }
@media (max-width: 40rem) {
	#mainsmall.site-hero { display: block; }
	#mainsmall.site-hero p { display: none; }
}

/* ---------------------------------------------------------------------------
 * Typographic scale
 *
 * wa-card slots its header into a region that inherits the document's heading
 * sizes, so an h2 inside a sidebar card rendered at full page-heading size.
 * These rules size headings by their role on the page rather than by tag.
 * ------------------------------------------------------------------------- */
.sidebar-module h2 { font-size: 1rem; margin: 0; letter-spacing: .02em; text-transform: uppercase; color: var(--wa-color-text-quiet); }
.series-box h3, .comment-list h4 { font-size: 1.125rem; margin: 0; }

.entry-card h1, .entry-card h2 { margin-block-start: 0; }
.entry-card h1 a, .entry-card h2 a { text-decoration: none; }
.entry-card h1 a:hover, .entry-card h2 a:hover { text-decoration: underline; }

/* /why visited links get their own colour: on an archive of 1,430 posts,
 * knowing which ones you have already read is genuinely useful navigation.
 * The site already did this -- the old colour was #8d32a4. */
main a:visited { color: var(--wa-color-visited, #8d32a4); }

/* Archive years collapse to months; the summary carries the year's post count. */
.archive-year { margin-block-end: var(--wa-space-2xs, .25rem); }
.archive-year .sidebar-list { max-height: none; }
.sidebar-note { margin: 0 0 var(--wa-space-s, .5rem); font-size: .875rem; color: var(--wa-color-text-quiet); }
.toc-sub { padding-inline-start: var(--wa-space-m, 1rem); }
#post-toc .sidebar-list ul { list-style: none; margin: 0; padding: 0; }
