/*
	base.css -- shared by every page on the site.

	Design tokens, the reset, typography and the components that appear both on
	the landing page and inside articles. Nothing here knows about the Dimension
	panel system; that lives in landing.css and is loaded only by index.html.

	Derived from Dimension by HTML5 UP (html5up.net | @ajlkn), CCA 3.0.
	Hand-maintained -- the original Sass sources were retired, see README.md.

	Fonts load via <link> in each page's <head>, not @import, so they don't
	block the stylesheet from rendering.
*/

/* Design tokens
   ------------------------------------------------------------------------
   Change a colour here and it changes everywhere. Every stylesheet in this
   project (base, landing, article, article-code) reads from these. */

:root {

	/* Surfaces */
	--bg: #1b1f22;
	--bg-overlay: rgba(19, 21, 25, 0.5);
	--bg-panel: rgba(27, 31, 34, 0.85);
	--bg-raised: rgba(255, 255, 255, 0.025);

	/* Text */
	--fg: #ffffff;
	--fg-light: rgba(255, 255, 255, 0.5);

	/* Lines & edges */
	--border: #ffffff;
	--border-bg: rgba(255, 255, 255, 0.075);
	--border-bg-alt: rgba(255, 255, 255, 0.175);
	--border-subtle: rgba(255, 255, 255, 0.05);

	/* Accent. --accent-rgb exists so it can be used with a custom alpha,
	   e.g. rgba(var(--accent-rgb), 0.08). */
	--accent: #1e90ff;
	--accent-rgb: 30, 144, 255;

	/* Status colours for the code-block chrome. The -rgb variants exist so
	   they can be used at an arbitrary alpha. */
	--ok-rgb: 80, 250, 123;
	--danger-rgb: 255, 99, 71;

	/* Shape & motion */
	--radius: 4px;
	--radius-lg: 0.75rem;
	--duration: 0.2s;

	/* Focus. Applied wherever :focus-visible needs a visible ring. */
	--focus-ring: 2px solid var(--accent);

	/* Type */
	--font-body: "Source Sans Pro", sans-serif;
	--font-mono: "Courier New", monospace;
	--tracking: 0.2rem;
	--tracking-heading: 0.5rem;

}

html, body, div, span, applet, object,
iframe, h1, h2, h3, h4, h5, h6, p, blockquote,
pre, a, abbr, acronym, address, big, cite,
code, del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var, b,
u, i, center, dl, dt, dd, ol, ul, li, fieldset,
form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td, article, aside,
canvas, details, embed, figure, figcaption,
footer, header, hgroup, menu, nav, output, ruby,
section, summary, time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;}

article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
	display: block;}

body {
	line-height: 1;
}

[hidden] {
	display: none !important;
}

ol, ul {
	list-style: none;
}

blockquote, q {
	quotes: none;
}

	blockquote:before, blockquote:after, q:before, q:after {
		content: '';
		content: none;
	}

table {
	border-collapse: collapse;
	border-spacing: 0;
}

body {
	-webkit-text-size-adjust: none;
}

mark {
	background-color: transparent;
	color: inherit;
}

input::-moz-focus-inner {
	border: 0;
	padding: 0;
}

input, select, textarea {
	-webkit-appearance: none;
	appearance: none;
}

/* Basic */

	@media screen and (max-width: 480px) {

		html, body {
			min-width: 320px;
		}

	}

	html {
		box-sizing: border-box;
	}

	*, *:before, *:after {
		box-sizing: inherit;
	}

	body {
		background: var(--bg);
	}

/* Wrapper (shared skeleton -- landing.css adds the full-height centring) */

	#wrapper {
		display: flex;
		flex-direction: column;
		position: relative;
		width: 100%;
		z-index: 3;
	}

/* Type */

	html {
		font-size: 16pt;
	}

		@media screen and (max-width: 1680px) {

			html {
				font-size: 12pt;
			}

		}

		@media screen and (max-width: 736px) {

			html {
				font-size: 11pt;
			}

		}

		@media screen and (max-width: 360px) {

			html {
				font-size: 10pt;
			}

		}

	body, input, select, textarea {
		color: var(--fg);
		font-family: var(--font-body);
		font-weight: 300;
		font-size: 1rem;
		line-height: 1.65;
	}

	a {
		transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out;
		border-bottom: dotted 1px var(--fg-light);
		text-decoration: none;
		color: inherit;
	}

		a:hover {
			border-bottom-color: transparent;
		}

	strong, b {
		color: var(--fg);
		font-weight: 600;
	}

	em, i {
		font-style: italic;
	}

	p {
		margin: 0 0 2rem 0;
	}

	h1, h2, h3, h4, h5, h6 {
		color: var(--fg);
		font-weight: 600;
		line-height: 1.5;
		margin: 0 0 1rem 0;
		text-transform: uppercase;
		letter-spacing: 0.2rem;
	}

		h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
			color: inherit;
			text-decoration: none;
		}

		h1.major, h2.major, h3.major, h4.major, h5.major, h6.major {
			border-bottom: solid 1px var(--fg);
			width: max-content;
			padding-bottom: 0.5rem;
			margin: 0 0 2rem 0;
		}

	h1 {
		font-size: 2.25rem;
		line-height: 1.3;
		letter-spacing: 0.5rem;
	}

	h2 {
		font-size: 1.5rem;
		line-height: 1.4;
		letter-spacing: 0.5rem;
	}

	h3 {
		font-size: 1rem;
	}

	h4 {
		font-size: 0.8rem;
	}

	h5 {
		font-size: 0.7rem;
	}

	h6 {
		font-size: 0.6rem;
	}

	@media screen and (max-width: 736px) {

		h1 {
			font-size: 1.75rem;
			line-height: 1.4;
		}

		h2 {
			font-size: 1.25em;
			line-height: 1.5;
		}

	}

	sub {
		font-size: 0.8rem;
		position: relative;
		top: 0.5rem;
	}

	sup {
		font-size: 0.8rem;
		position: relative;
		top: -0.5rem;
	}

	blockquote {
		border-left: solid 4px var(--fg);
		font-style: italic;
		margin: 0 0 2rem 0;
		padding: 0.5rem 0 0.5rem 2rem;
	}

	code {
		background: var(--border-bg);
		border-radius: 4px;
		font-family: var(--font-mono);
		font-size: 0.9rem;
		margin: 0 0.25rem;
		padding: 0.25rem 0.65rem;
	}

	pre {
		-webkit-overflow-scrolling: touch;
		font-family: var(--font-mono);
		font-size: 0.9rem;
		margin: 0 0 2rem 0;
	}

		pre code {
			display: block;
			line-height: 1.75;
			padding: 1rem 1.5rem;
			overflow-x: auto;
		}

	hr {
		border: 0;
		border-bottom: solid 1px var(--fg);
		margin: 2.75rem 0;
	}

/* Image */

	.image {
		border-radius: 4px;
		border: 0;
		display: inline-block;
		position: relative;
	}


		.image img {
			border-radius: 4px;
			display: block;
		}

/* List */

	ol {
		list-style: decimal;
		margin: 0 0 2rem 0;
		padding-left: 1.25em;
	}

		ol li {
			padding-left: 0.25em;
		}

	ul {
		list-style: disc;
		margin: 0 0 2rem 0;
		padding-left: 1em;
	}

		ul li {
			padding-left: 0.5em;
		}

		ul.alt {
			list-style: none;
			padding-left: 0;
		}

			ul.alt li {
				border-top: solid 1px var(--fg);
				padding: 0.5em 0;
			}

				ul.alt li:first-child {
					border-top: 0;
					padding-top: 0;
				}

	dl {
		margin: 0 0 2rem 0;
	}

		dl dt {
			display: block;
			font-weight: 600;
			margin: 0 0 1rem 0;
		}

		dl dd {
			margin-left: 2rem;
		}

/* Table */

	.table-wrapper {
		-webkit-overflow-scrolling: touch;
		overflow-x: auto;
	}

	table {
		margin: 0 0 2rem 0;
		width: 100%;
	}

		table tbody tr {
			border: solid 1px var(--fg);
			border-left: 0;
			border-right: 0;
		}

			table tbody tr:nth-child(2n + 1) {
				background-color: var(--border-bg);
			}

		table td {
			padding: 0.75em 0.75em;
		}

		table th {
			color: var(--fg);
			font-size: 0.9em;
			font-weight: 600;
			padding: 0 0.75em 0.75em 0.75em;
			text-align: left;
		}

		table thead {
			border-bottom: solid 2px var(--fg);
		}

		table tfoot {
			border-top: solid 2px var(--fg);
		}

		table.alt {
			border-collapse: separate;
		}

			table.alt tbody tr td {
				border: solid 1px var(--fg);
				border-left-width: 0;
				border-top-width: 0;
			}

				table.alt tbody tr td:first-child {
					border-left-width: 1px;
				}

			table.alt tbody tr:first-child td {
				border-top-width: 1px;
			}

			table.alt thead {
				border-bottom: 0;
			}

			table.alt tfoot {
				border-top: 0;
			}

/* Button */

	input[type="submit"],
	input[type="reset"],
	input[type="button"],
	button,
	.button {
		-webkit-appearance: none;
		appearance: none;
		transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
		background-color: transparent;
		border-radius: 4px;
		border: 0;
		box-shadow: inset 0 0 0 1px var(--fg);
		color: var(--fg) !important;
		cursor: pointer;
		display: inline-block;
		font-size: 0.8rem;
		font-weight: 300;
		height: 2.75rem;
		letter-spacing: 0.2rem;
		line-height: 2.75rem;
		outline: 0;
		padding: 0 1.25rem 0 1.35rem;
		text-align: center;
		text-decoration: none;
		text-transform: uppercase;
		white-space: nowrap;
	}

		input[type="submit"]:hover,
		input[type="reset"]:hover,
		input[type="button"]:hover,
		button:hover,
		.button:hover {
			background-color: var(--border-bg);
		}

		input[type="submit"]:active,
		input[type="reset"]:active,
		input[type="button"]:active,
		button:active,
		.button:active {
			background-color: var(--border-bg-alt);
		}

		input[type="submit"].icon:before,
		input[type="reset"].icon:before,
		input[type="button"].icon:before,
		button.icon:before,
		.button.icon:before {
			margin-right: 0.5em;
		}

		input[type="submit"].fit,
		input[type="reset"].fit,
		input[type="button"].fit,
		button.fit,
		.button.fit {
			width: 100%;
		}

		input[type="submit"].small,
		input[type="reset"].small,
		input[type="button"].small,
		button.small,
		.button.small {
			font-size: 0.6rem;
			height: 2.0625rem;
			line-height: 2.0625rem;
		}

		input[type="submit"].primary,
		input[type="reset"].primary,
		input[type="button"].primary,
		button.primary,
		.button.primary {
			background-color: var(--fg);
			color: var(--bg) !important;
			font-weight: 600;
		}

		input[type="submit"].disabled, input[type="submit"]:disabled,
		input[type="reset"].disabled,
		input[type="reset"]:disabled,
		input[type="button"].disabled,
		input[type="button"]:disabled,
		button.disabled,
		button:disabled,
		.button.disabled,
		.button:disabled {
			pointer-events: none;
			cursor: default;
			opacity: 0.25;
		}

	input[type="submit"],
	input[type="reset"],
	input[type="button"],
	button {
		line-height: calc(2.75rem - 2px);
	}

/* Blog grid */

	#main article#projects {
		width: 100%;
		max-width: 55rem;
	}

	#main article#projects > ul {
		margin-top: 1.5rem;
	}

	#main article#projects > ul > li {
		margin: 0 0 1.25rem 0;
	}

	#main article#projects > ul > li:last-child {
		margin-bottom: 0;
	}

	#main article#projects > ul > li > ul {
		margin-top: 0.75rem;
	}

	#main article#projects > ul > li > ul > li {
		margin: 0 0 0.5rem 0;
	}

	#main article#projects > ul > li > ul > li:last-child {
		margin-bottom: 0;
	}

	@media screen and (max-width: 1080px) {

		#main article#projects {
			max-width: none;
		}

	}

	#main article#articles {
		width: 100%;
		max-width: 75rem;
		padding: 4.5rem 2rem 1.5rem 2rem;
	}

	@media screen and (max-width: 1280px) {

		#main article#articles {
			max-width: 64rem;
		}

	}

	@media screen and (max-width: 1080px) {

		#main article#articles {
			max-width: none;
			padding: 3.5rem 1.5rem 0.5rem 1.5rem;
		}

	}

	.posts-grid {
		display: grid;
		grid-template-columns: repeat(3, minmax(16rem, 1fr));
		gap: 1.75rem;
		margin-top: 2rem;
	}

	.post-card {
		position: relative;   /* anchors the stretched title link below */
		background-color: var(--bg-raised);
		border: 1px solid var(--border-subtle);
		border-radius: var(--radius-lg);
		padding: 1.75rem;
		display: flex;
		flex-direction: column;
		min-height: 100%;
		box-shadow: 0 1.25rem 2.5rem rgba(0, 0, 0, 0.25);
		transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
	}

		.post-card:hover,
		.post-card:focus-within {
			transform: translateY(-0.35rem);
			box-shadow: 0 1.75rem 3rem rgba(0, 0, 0, 0.35);
		}

		/* Keyboard users get the same "this card is active" cue as mouse users. */
		.post-card:focus-within {
			border-color: rgba(var(--accent-rgb), 0.5);
		}

		/* The whole card is the click target, not just the title. */
		.post-card__title a:after {
			content: '';
			position: absolute;
			inset: 0;
			z-index: 1;
		}

	/* Category label. Gives the grid something to scan by without needing
	   thumbnails -- most of this content is terminal output anyway. */
	.post-card__category {
		margin: 0 0 0.5rem 0;
		color: var(--accent);
		font-size: 0.7rem;
		font-weight: 600;
		letter-spacing: var(--tracking);
		text-transform: uppercase;
	}

	.post-card__title {
		margin: 0 0 0.5rem 0;
		line-height: 1.3;
	}

		.post-card__title a {
			border-bottom: 0;
		}

		.post-card__title a:hover {
			color: var(--accent);
		}

	.post-meta {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		gap: 0.75rem;
		font-size: 0.7rem;
		letter-spacing: var(--tracking);
		text-transform: uppercase;
		margin: 0 0 0.75rem 0;
		/* Colour rather than opacity, so a status pill inside can render at full
		   strength -- opacity on the parent would mute it to 65% regardless. */
		color: var(--fg-light);
	}

		/* No date yet? Don't leave a gap. */
		.post-meta:empty {
			display: none;
		}

	.post-card__excerpt {
		margin: 0 0 1rem 0;
		font-size: 0.9rem;
		line-height: 1.5;
	}

	/* Planned posts stay on the grid so the roadmap reads, but they are not
	   links -- nobody spends a click to find an empty page. */
	.post-card--planned {
		border-style: dashed;
		box-shadow: none;
		background-color: rgba(255, 255, 255, 0.015);
	}

		.post-card--planned:hover,
		.post-card--planned:focus-within {
			transform: none;
			box-shadow: none;
		}

	@media screen and (max-width: 980px) {

		.posts-grid {
			grid-template-columns: repeat(2, minmax(0, 1fr));
		}

	}

	@media screen and (max-width: 600px) {

		.posts-grid {
			grid-template-columns: 1fr;
		}

	}

	/* Status pill for planned article cards. */
	.status-pill {
		display: inline-block;
		padding: 0.15rem 0.6rem;
		border-radius: 999px;
		border: solid 1px currentColor;
		font-size: 0.65rem;
		font-weight: 600;
		letter-spacing: var(--tracking);
		text-transform: uppercase;
		white-space: nowrap;
	}

	.status-pill--planned {
		color: var(--fg-light);
	}

/* Page transitions
   ------------------------------------------------------------------------
   Articles are separate documents now, so the panel's fade-out on close had
   nowhere to live. Cross-document view transitions give it back: the outgoing
   page fades to the incoming one on any same-origin navigation.

   Progressive enhancement -- browsers without support just navigate normally.
   Both sides of a navigation must opt in, which is why this lives in
   base.css rather than in landing.css or article.css. */

@view-transition {
	navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
	animation-duration: 0.28s;
	animation-timing-function: ease-in-out;
}

/* The `*` reset further down does not match view-transition pseudo-elements,
   so reduced motion has to be handled explicitly here. */
@media (prefers-reduced-motion: reduce) {

	::view-transition-group(*),
	::view-transition-old(*),
	::view-transition-new(*) {
		animation: none !important;
	}

}

/* Accessibility helpers */

	/* Visible only to screen readers. General-purpose utility -- use it whenever
	   a link's visible text would be ambiguous out of context. */
	.sr-only {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
		border: 0;
	}

	.skip-link {
		position: absolute;
		top: 0;
		left: 0;
		z-index: 20000;
		padding: 0.75rem 1.25rem;
		background: var(--bg);
		border: solid 1px var(--border);
		border-bottom: solid 1px var(--border);
		color: var(--fg);
		font-size: 0.7rem;
		letter-spacing: var(--tracking);
		text-transform: uppercase;
		transform: translateY(-150%);
	}

		.skip-link:focus {
			transform: translateY(0);
		}

	/* One consistent focus ring for everything that can take focus. Mouse users
	   never see it; keyboard users always do. */
	a:focus-visible,
	button:focus-visible,
	[tabindex]:focus-visible,
	input:focus-visible,
	select:focus-visible,
	textarea:focus-visible {
		outline: var(--focus-ring);
		outline-offset: 2px;
	}

	/* Zoomable article links retain a clear pointer affordance. */
	.image[data-zoomable-bound] {
		cursor: zoom-in;
		border-bottom: 0;
	}

	@media (prefers-reduced-motion: reduce) {

		*, *:before, *:after {
			animation-duration: 0.01ms !important;
			animation-iteration-count: 1 !important;
			transition-duration: 0.01ms !important;
			scroll-behavior: auto !important;
		}

	}
