:root {
	--bg: #fff;
	--text: #2e2f30;
	--outline: #fff;
	--button-radius: 16px;
	--button-size: 32px;
	--icon-size: 16px;
	--icon-offset: 8px;
	--blur: 30px;
	--brightness: 150%;
	--button-bg: rgba(200, 200, 200, .25);
	--button-bg-hover: rgba(200, 200, 200, .5);
	--button-bg-active: rgba(200, 200, 200, .25);
	--overlay-hover: rgba(0, 0, 0, .25);
	--overlay-active: rgba(0, 0, 0, .5);
	--nav-width: 80px;
	--link-offset: 24px;
	--font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
	--ease-bounce: cubic-bezier(.22, 1.07, .36, 1);
	--transition-duration: .3s;
	--grid-radius: 8px;
	--text-size: 10pt;
	--border-radius: 32px;
	--caption-scrim: linear-gradient(to bottom, transparent, rgba(0, 0, 0, .8));

	@media (prefers-color-scheme: dark) {
		--bg: #000;
		--text: #eee;
		--outline: #000;
	}
}

* {
	padding: 0;
	margin: 0;
	list-style: none;
	font-size: 1em;
	box-sizing: border-box;
}

html, body {
	min-height: 100%;
	display: flex;
}

body {
	flex-grow: 1;
	font: 16px/24px var(--font-stack);
	background: var(--bg);
	color: var(--text);
}

/* PHOTO GRID — CSS columns masonry */

.grid {
	columns: 300px;
	column-gap: 2px;
	width: 100vw;

	& .item {
		break-inside: avoid;
		margin-bottom: 2px;
		position: relative;
		line-height: 0;

		& img {
			width: 100%;
			height: auto;
			display: block;
			border-radius: var(--grid-radius);

			&[src$=".gif"] {
				image-rendering: pixelated;
			}
		}

		& .open {
			position: absolute;
			inset: 0;
			border-radius: var(--grid-radius);
			text-indent: 150%;
			overflow: hidden;
			white-space: nowrap;
		}

		& .open {
			cursor: pointer;
			background-color: transparent;
			transition: background-color .15s ease-out;

			&:hover, &:focus {
				background-color: var(--overlay-hover);
			}

			&:active {
				background-color: var(--overlay-active);
			}
		}

		& .previous  { display: none; }
		& .next      { display: none; }
		& .actions   { display: none; }
		& .caption   { display: none; }

		/* PHOTO DETAIL — fullscreen overlay */

		&.target {
			position: fixed;
			inset: 0;
			width: 100vw;
			height: 100vh;
			height: 100dvh;
			z-index: 10;
			background: var(--bg);
			display: flex;
			align-items: center;
			justify-content: center;
			line-height: normal;

			& figure {
				width: 100%;
				height: 100%;
			}

			& img,
			& .lightbox-video {
				width: 100%;
				height: 100%;
				object-fit: contain;
			}

			& .open  { display: none; }

			& .previous,
			& .next {
				display: flex;
				position: absolute;
				top: 0;
				bottom: 0;
				z-index: 20;
				width: 25vw;
				align-items: center;
				transition: background-color .2s ease-out, opacity .5s ease-out;

				& .button {
					background-image: url(../img/icon-left.svg);
					pointer-events: none;
					transition: background-color .2s ease-out, transform .2s ease-out;
				}

				&:hover {
					background-color: rgba(0, 0, 0, .05);

					& .button {
						background-color: var(--button-bg-hover);
						transform: scale(1.1);
					}
				}
				&:active .button { background-color: var(--button-bg-active); }
			}

			& .previous {
				left: 0;
				cursor: pointer;
				justify-content: flex-start;
				padding-left: 24px;
			}

			& .next {
				right: 0;
				left: auto;
				cursor: pointer;
				justify-content: flex-end;
				padding-right: 24px;

				& .button {
					background-image: url(../img/icon-right.svg);
				}
			}

			& .previous.faded,
			& .next.faded {
				opacity: 0;
				pointer-events: none;
			}

			& .actions {
				display: flex;
				position: fixed;
				top: var(--link-offset);
				right: var(--link-offset);
				z-index: 21;
				gap: 8px;
				transition: opacity .5s ease-out;

				&.faded {
					opacity: 0;
					pointer-events: none;
				}

				& .button {
					transition: background-color .1s linear;
					cursor: pointer;
				}

				& .share { background-image: url(../img/icon-share.svg); }
				& .download { background-image: url(../img/icon-download.svg); }
				& .close {
					background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23fff' d='M3.293 3.293a1 1 0 0 1 1.414 0L8 6.586l3.293-3.293a1 1 0 1 1 1.414 1.414L9.414 8l3.293 3.293a1 1 0 0 1-1.414 1.414L8 9.414l-3.293 3.293a1 1 0 0 1-1.414-1.414L6.586 8 3.293 4.707a1 1 0 0 1 0-1.414Z'/%3E%3C/svg%3E");
					background-color: rgba(0, 0, 0, .6);
					outline: 2px solid rgba(255, 255, 255, .5);
					outline-offset: -2px;

					&:hover { background-color: rgba(0, 0, 0, .75); }
					&:active { background-color: rgba(0, 0, 0, .5); }
				}
			}

			/* CAPTION — lightbox metadata */
			& .caption {
				display: flex;
				flex-direction: column;
				align-items: flex-start;
				gap: 4px;
				position: fixed;
				left: 0;
				right: 0;
				bottom: 0;
				top: auto;
				color: #fff;
				z-index: 21;
				transition: opacity .5s ease-out;
				pointer-events: none;
				padding: 10rem;

				&.faded {
					opacity: 0;
					pointer-events: none;
					& > * { animation: none; }
				}

				&::before {
					content: '';
					position: absolute;
					left: 0;
					right: 0;
					bottom: 0;
					height: 50vh;
					background: var(--caption-scrim);
					z-index: -1;
					pointer-events: none;
					animation: fade-in calc(var(--transition-duration) * 2) ease-out both;
				}
			}

			& .caption-title,
			& .caption-desc {
				display: block;
				animation: caption-in var(--transition-duration) var(--ease-bounce) both;
				max-width: 70rem;
			}
			& .caption-title { font-size: calc(var(--text-size) * 2); font-weight: 900; line-height: 1.8; animation-delay: var(--transition-duration); }
			& .caption-desc { font-size: calc(var(--text-size) * 1.5); font-weight: 400; line-height: 1.8; animation-delay: calc(var(--transition-duration) + .1s); }

			& .caption-meta {
				display: flex;
				flex-wrap: wrap;
				align-items: baseline;
				margin-top: 1rem;
				gap: 12px;
				animation: caption-in var(--transition-duration) var(--ease-bounce) both;
				animation-delay: calc(var(--transition-duration) + .2s);
			}
			& .caption-year {
				font-size: calc(var(--text-size) * .85);
				opacity: .5;
				font-weight: 400;
			}
			& .caption-meta .badge {
				display: inline-block;
				font-size: calc(var(--text-size) * .75);
				font-weight: 600;
				letter-spacing: .05em;
				text-transform: uppercase;
				padding: 2px 6px;
				border: 1px solid rgba(255, 255, 255, .4);
				border-radius: 4px;
				line-height: 1.4;
				opacity: .8;
			}

			& .caption-pin {
				all: unset;
				display: inline-block;
				width: .7em;
				height: .7em;
				padding: 2px;
				margin-left: .4em;
				vertical-align: middle;
				cursor: pointer;
				border-radius: 50%;
				background: no-repeat center / 65%;
				background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none'%3E%3Cpath d='M3 1.5h10l-1.5 8.5h-7z' stroke='%23fff' stroke-width='2.5' stroke-linejoin='round'/%3E%3Cline x1='8' y1='10.5' x2='8' y2='14.5' stroke='%23fff' stroke-width='2.5' stroke-linecap='round'/%3E%3C/svg%3E");
				pointer-events: auto;
				animation: caption-in var(--transition-duration) var(--ease-bounce) both;
				animation-delay: calc(var(--transition-duration) + .3s);
				opacity: .5;
				transition: opacity var(--transition-duration) var(--ease-bounce),
					background-color var(--transition-duration) var(--ease-bounce);

				&:hover { opacity: .8; }
				&.pinned {
					opacity: 1;
					background-color: #fff;
					background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M3 1.5h10l-1.5 8.5h-7z' fill='%23000' stroke-linejoin='round'/%3E%3Cline x1='8' y1='10.5' x2='8' y2='14.5' stroke='%23000' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
				}
			}

			& .caption a {
				color: inherit;
				pointer-events: auto;
			}
			& .caption code {
				background: rgba(255, 255, 255, .15);
				padding: 1px 4px;
				border-radius: 3px;
			}
		}
	}

	/* RESPONSIVE — single column on narrow portrait screens */

	@media (max-aspect-ratio: 1/1) and (max-width: 640px) {
		columns: 1;

		& .item.target {
			& .caption {
				padding: 4rem 1rem;
			}
		}
	}
}

/* BUTTON BASE — common styles for all button-like elements */

.button {
	display: block;
	border-radius: var(--button-radius);
	text-indent: 150%;
	overflow: hidden;
	white-space: nowrap;
	width: var(--button-size);
	height: var(--button-size);
	background: var(--button-bg) no-repeat var(--icon-offset) / var(--icon-size);
	backdrop-filter: blur(var(--blur));
	transition: background-color .2s ease-out;

	&:hover { background-color: var(--button-bg-hover); }
	&:active { background-color: var(--button-bg-active); }

	&.large {
		--button-size-large: calc(2 * var(--button-size));
		--icon-size-large: calc(2 * var(--icon-size));
		--icon-offset-large: calc(2 * var(--icon-offset));

		width: var(--button-size-large);
		height: var(--button-size-large);
		background-size: var(--icon-size-large);
		background-position: var(--icon-offset-large);

		@media (max-aspect-ratio: 1/1) and (max-width: 640px) {
			width: var(--button-size);
			height: var(--button-size);
			background-size: var(--icon-size);
			background-position: var(--icon-offset);
		}
	}
}

/* SOCIAL LINKS */

.links {
	position: fixed;
	right: var(--link-offset);
	bottom: var(--link-offset);
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 8px;
	z-index: 30;

	& .button {
		backdrop-filter: blur(var(--blur)) brightness(var(--brightness));
		box-shadow: 0 0 0 0 var(--button-bg-hover);
		transition: background-color var(--transition-duration) var(--ease-bounce),
		            box-shadow var(--transition-duration) var(--ease-bounce);

		&:hover {
			background-color: var(--button-bg-hover);
			box-shadow: 0 0 0 6px var(--button-bg-hover);
		}
		&:active {
			background-color: var(--button-bg-active);
			box-shadow: 0 0 0 2px var(--button-bg-active);
			transition-duration: .1s;
		}
	}

	& .github a    { background-image: url(../img/icon-github.svg); }
	& .twitter a   { background-image: url(../img/icon-twitter.svg); }
	& .mastodon a  { background-image: url(../img/icon-mastodon.svg); }
	& .instagram a { background-image: url(../img/icon-instagram.svg); }
	& .pixelfed a  { background-image: url(../img/icon-pixelfed.svg); }
	& .rss {
		position: fixed;
		top: var(--link-offset);
		right: var(--link-offset);

		& a { background-image: url(../img/icon-rss.svg); }
	}

	& .avatar a {
		text-indent: 0;
		padding: 0;
		background: none;
		width: 48px;
		height: 48px;
		border-radius: 50%;

		& img {
			width: 100%;
			height: 100%;
			display: block;
			border-radius: 50%;
			border: 2px solid #fff;
			box-sizing: border-box;
		}
	}
}

body:has(.item.target) .links .rss { display: none; }

/* 404 */

.four-oh-four {
	flex-grow: 1;
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: 64px;
	align-items: center;
	justify-content: center;
	text-align: center;

	& h1 {
		font-size: 32px;
		line-height: 48px;
		font-weight: 700;
	}

	& p {
		margin-bottom: 32px;
	}

	& a {
		display: block;
		border-radius: var(--button-radius);
		backdrop-filter: blur(var(--blur));
		background-color: var(--button-bg);
		text-decoration: none;
		font-size: 13px;
		line-height: var(--button-size);
		text-transform: uppercase;
		padding: 0 12px;
		color: rgba(0, 0, 0, .75);
		font-weight: 600;

		&:hover { background-color: var(--button-bg-hover); }
	}
}

/* TOAST */

.toast {
	position: fixed;
	bottom: var(--link-offset);
	left: 50%;
	translate: -50% 0;
	z-index: 40;
	padding: 8px 16px;
	border-radius: var(--button-radius);
	background: var(--text);
	color: var(--bg);
	font: 13px/var(--button-size) var(--font-stack);
	white-space: nowrap;
	animation: toast 2s ease-out forwards;
	pointer-events: none;
}

/* ANIMATIONS */

@keyframes caption-in {
	from { opacity: 0; translate: 0 -12px; }
	to   { opacity: 1; translate: 0 0; }
}

@keyframes fade-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@keyframes slide-from-right {
	from { translate: 30% 0; opacity: 0; }
	to   { translate: 0 0; opacity: 1; }
}

@keyframes slide-from-left {
	from { translate: -30% 0; opacity: 0; }
	to   { translate: 0 0; opacity: 1; }
}

@keyframes toast {
	0%   { opacity: 0; translate: -50% 16px; }
	15%  { opacity: 1; translate: -50% 0; }
	85%  { opacity: 1; translate: -50% 0; }
	100% { opacity: 0; translate: -50% -8px; }
}

.slide-next figure { animation: slide-from-right var(--transition-duration) var(--ease-bounce); }
.slide-prev figure { animation: slide-from-left var(--transition-duration) var(--ease-bounce); }

