/*
Theme Name: Patoczka
Theme URI: https://patoczka.net/
Author: Adam Kramarczyk
Author URI: https://helban.dev
Description: Lean theme for the patoczka.net travel archive. Carries the palette of the
 original FrontPage home page and renders one page per gallery, with every old photo
 address surviving as an anchor.
Version: 0.10.0
Requires at least: 6.5
Requires PHP: 8.2
License: Proprietary
Text Domain: patoczka
*/

/* Palette measured on his live site with getComputedStyle, not guessed from markup.

   His archive wears THREE skins, and the difference is not decoration: the showcase gallery a
   home-page tile lands on is navy #003366, the other sub galleries of the same trip are dark
   green #135718, and the 21 snapshot galleries are burnt orange #D07000. He asked on
   2026-08-21 for that to survive the migration. Which gallery wears which is read off his own
   pages by inventory/parse_gallery_chrome.py and arrives here as a body class.

   His HOME page is a fourth skin: a sepia world map behind everything, #FFCC66 only in the
   navigation strip, maroon titles, #CC3300 descriptions. It has its own section at the bottom
   of this file.

   Two things are deliberately not copied literally. Pure #FFFF00 as 13 px body text is
   uncomfortable to read, so text uses a softened gold and full-strength yellow stays where it
   is a graphic element: the hairline around every thumbnail, which is the line his own JPEGs
   already carry. And the orange skin takes dark text rather than his white, because white on
   #D07000 measures 3.5:1 — his own links on those pages are black, so the ink here is his
   too, just the other half of his palette. */
:root {
	--column: 1180px;
	--thumb-max: 200px;

	/* The navy skin is also the fallback: a gallery whose skin meta never arrived renders as
	   the showcase pages do rather than as something that belongs to no page on his site. */
	--page-bg: #003366;
	--header-bg: #002347;
	--panel-bg: #0a4076;
	--page-ink: #cfe0f0;
	--page-muted: #9fb6cc;
	--page-title: #ffcc66;
	--link: #ffd633;
	--link-hover: #ffffff;
	--rail-bg: #0105b1;
	--rail-ink: #ffe9a8;
	/* The "Main Travel Page" button, in the amber of his own home-page navigation strip. It
	   stays the same on all three skins on purpose: it is the same destination everywhere. */
	--rail-home-bg: #ffcc66;
	--rail-home-ink: #2b1a00;
	/* The top bar has its own ink because it is dark on all three skins, including the one
	   whose page is light. Reusing the page ink there put brown on brown at 1.8:1. */
	--header-ink: #ffcc66;
	--header-muted: #9fb6cc;

	--thumb-line: #ffff00;
	--gold: #ffd633;
	--gold-soft: #ffe9a8;
	--amber: #ffcc66;
	--accent: #cc3300;
	--maroon: #800000;
}

/* His "Additional Images from ..." and other sibling galleries. */
body.skin-green {
	--page-bg: #135718;
	--header-bg: #0b3a0f;
	--panel-bg: #17651d;
	--page-ink: #e3f1dd;
	--page-muted: #b3ceab;
	--page-title: #ffe08a;
	--rail-bg: #0e4712;
	--header-ink: #ffe08a;
	--header-muted: #b3ceab;
}

/* His snapshot galleries, the ones built as framesets. Dark ink, as his own links are. */
body.skin-sonora {
	--page-bg: #d07000;
	--header-bg: #8a4a00;
	--panel-bg: #e08420;
	--page-ink: #20140a;
	--page-muted: #2e1b04;
	--page-title: #ffffff;
	--link: #1a1000;
	--link-hover: #ffffff;
	--rail-bg: #8a4a00;
	--rail-ink: #ffffff;
	--header-ink: #ffffff;
	--header-muted: #f3ddc4;
}

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

body {
	margin: 0;
	/* His headings ask for Eras Demi ITC, which ships with MS Office and so exists on his
	   machine and almost nowhere else; his gallery pages fall back to Comic Sans MS.
	   TECH [wyglad-home] allows a compatible substitute, and this humanist stack stands in
	   until the home page is rebuilt and the substitute can be judged next to it. */
	font-family: "Trebuchet MS", "Segoe UI", system-ui, -apple-system, sans-serif;
	font-size: 17px;
	line-height: 1.55;
	color: var(--page-ink);
	background: var(--page-bg);
}

a {
	color: var(--link);
}

a:hover,
a:focus-visible {
	color: var(--link-hover);
}

img {
	max-width: 100%;
	height: auto;
}

.site-header {
	background: var(--header-bg);
	color: var(--header-ink);
	padding: 14px 20px;
	border-bottom: 1px solid rgba(255, 214, 51, 0.35);
}

.site-header__inner {
	max-width: var(--column);
	margin: 0 auto;
	display: flex;
	flex-wrap: wrap;
	gap: 6px 18px;
	align-items: baseline;
	justify-content: space-between;
}

.site-header__title {
	margin: 0;
	font-size: 1.25rem;
	letter-spacing: 0.02em;
}

.site-header__title a {
	color: inherit;
	text-decoration: none;
}

.site-header__tagline {
	margin: 0;
	font-size: 0.9rem;
	color: var(--header-muted);
}

.site-main {
	max-width: var(--column);
	margin: 22px auto 40px;
	padding: 6px clamp(16px, 3vw, 34px) 34px;
}

.page-title {
	margin: 0 0 4px;
	color: var(--page-title);
	font-size: clamp(1.5rem, 1.1rem + 1.5vw, 2.1rem);
	line-height: 1.2;
}

.gallery-lede {
	margin: 0 0 18px;
	color: var(--page-muted);
	font-size: 0.95rem;
}

.gallery-shared-caption {
	margin: 0 0 20px;
	padding: 10px 14px;
	border-left: 3px solid var(--thumb-line);
	background: var(--panel-bg);
	color: var(--page-ink);
}

/* Text he types around the Gallery block on a page of his own. A paragraph's width, so a
   line of introduction does not run the full 1180 px column. */
.gallery-intro {
	max-width: 70ch;
	margin: 0 0 20px;
	color: var(--page-ink);
}

.gallery-intro > :first-child {
	margin-top: 0;
}

.gallery-intro > :last-child {
	margin-bottom: 0;
}

/* The gallery body: his left rail of trip links, then the thumbnails.
   The rail sits in the left border of every one of his gallery pages and is the only way
   into 86 of the 128 galleries, which the home page never links.

   The menu is set apart from the photographs by a gap and a yellow rule, his request of
   2026-08-22. The rule is drawn on the aside and so runs the height of the menu rather than
   the height of the page: a gallery of ninety photographs would otherwise carry a yellow line
   several screens long past nothing at all. */
.gallery-layout {
	display: flex;
	align-items: flex-start;
	gap: 34px;
}

.gallery-aside {
	flex: 0 0 122px;
	display: flex;
	flex-direction: column;
	gap: 18px;
	padding-right: 22px;
	border-right: 2px solid var(--thumb-line);
}

/* The short line he asked for between his trip and the rest of the site. Its width is set
   against the buttons above it rather than the column, so it reads as a divider inside the
   menu and not as another border. */
.gallery-aside__rule {
	width: 60%;
	margin: 2px auto;
	border: 0;
	border-top: 2px solid var(--thumb-line);
}

.gallery-rail {
	flex: 0 0 auto;
}

/* Two labels that exist for the phone only. Beside the photographs the menu is a border with
   the title above the grid and neither is needed; stacked above the thumbnails, both are, and
   they are switched on in the 720 px query rather than switched off in it, so the desktop the
   client already accepted on 2026-08-23 cannot change by accident. */
.gallery-rail__caption,
.gallery-grid-heading {
	display: none;
}

/* Five galleries keep a route map under the trip links, with his own caption over it and a
   link to the large version. The caption sits ABOVE the picture for the same reason the photo
   caption does. */
.gallery-maps {
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.gallery-map {
	margin: 0;
}

.gallery-map__caption {
	display: block;
	margin-bottom: 5px;
	font-size: 0.78rem;
	line-height: 1.25;
	text-align: center;
	color: var(--page-ink);
}

.gallery-map__link {
	display: block;
	line-height: 0;
}

.gallery-map__link img {
	display: block;
	width: 100%;
	height: auto;
	border: 1px solid var(--thumb-line);
}

.gallery-map__link:hover img,
.gallery-map__link:focus-visible img {
	outline: 2px solid var(--link-hover);
	outline-offset: 1px;
}

.gallery-rail__list {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.gallery-rail__link {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 62px;
	padding: 8px 6px;
	text-align: center;
	font-size: 0.78rem;
	line-height: 1.25;
	background: var(--rail-bg);
	border: 1px solid var(--thumb-line);
	color: var(--rail-ink);
	text-decoration: none;
}

.gallery-rail__link:hover,
.gallery-rail__link:focus-visible {
	color: var(--rail-ink);
	outline: 2px solid var(--link-hover);
	outline-offset: 1px;
}

/* The way back to the home page, asked on 2026-08-22 to stand out from its neighbours.
   It is given the amber of his own home-page strip and dark text, so the button wears the
   colour of the page it leads to, and that reads the same way on all three gallery skins.
   Weight and a thicker line carry the difference for anyone who cannot see the colour. */
.gallery-rail__link--home {
	background: var(--rail-home-bg);
	color: var(--rail-home-ink);
	border-width: 2px;
	font-weight: 700;
}

.gallery-rail__link--home:hover,
.gallery-rail__link--home:focus-visible {
	color: var(--rail-home-ink);
}

/* Thumbnails float on the background at their own proportions, with nothing around them but
   the thin yellow line. His request of 2026-08-21, and it is how his own pages read: an outer
   frame of a fixed shape had to letterbox the portraits to keep the tiles equal, which is the
   "larger yellow frames" he asked to lose.

   The line is drawn here rather than left to the photographs. His current JPEGs carry a 1 px
   yellow border baked into the pixels, but it is 1 px of a 500 px file, so it half disappears
   in a scaled-down thumbnail — and the larger scans he plans to swap in over the winter will
   not carry it at all. Drawn in the theme, the look survives both. */
.gallery-grid {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px;
	margin: 0;
	padding: 0;
	list-style: none;
	flex: 1 1 auto;
	min-width: 0;
}

.gallery-item {
	margin: 0;
}

.gallery-item__link {
	display: block;
	text-decoration: none;
	line-height: 0;
}

.gallery-item__link img {
	display: block;
	width: auto;
	height: auto;
	max-width: var(--thumb-max);
	max-height: var(--thumb-max);
	border: 1px solid var(--thumb-line);
}

/* An outline rather than a border on hover: a border would change the thumbnail's size and
   push every neighbour along the row. */
.gallery-item__link:hover img,
.gallery-item__link:focus-visible img {
	outline: 2px solid var(--link-hover);
	outline-offset: 1px;
}

.gallery-item__link:focus-visible {
	outline: none;
}

/* The /galleries/ index: one cover per gallery, with the gallery's name under it. Equal
   tiles here on purpose, because this is a list of 128 names and a ragged one is hard to
   read down. It is a different job from the thumbnails inside a gallery. */
.gallery-index {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr));
	grid-auto-rows: 1fr;
	gap: 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.gallery-index__item {
	margin: 0;
	display: flex;
}

.gallery-index__link {
	display: flex;
	flex-direction: column;
	width: 100%;
	text-decoration: none;
}

.gallery-index__cover {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 3 / 2;
	overflow: hidden;
	background: var(--panel-bg);
	border: 1px solid var(--thumb-line);
}

.gallery-index__cover img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
}

.gallery-index__name {
	display: block;
	min-height: 2.7em;
	margin-top: 7px;
	font-size: 0.82rem;
	line-height: 1.35;
	color: var(--page-ink);
}

.lightbox {
	position: fixed;
	inset: 0;
	z-index: 50;
	display: none;
	align-items: center;
	justify-content: center;
	padding: 3vh 3vw;
	background: rgba(0, 18, 38, 0.95);
}

.lightbox[open],
.lightbox.is-open {
	display: flex;
}

.lightbox__figure {
	margin: 0;
	max-width: 100%;
	max-height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
}

/* The archive's photographs are small: 86% of them are 401-600 px on the long side. Blowing
   a 600 px scan up to a 1440 px screen only shows the JPEG artefacts, so the lightbox shows
   the file at its own size and simply stops there. */
.lightbox__figure img {
	max-width: 100%;
	/* Two ceilings. 72vh leaves room for the caption above it, so a tall photograph on a short
	   window cannot push the caption off the top of the screen. The 650px is the height his
	   Fiji select photographs already have, and it is what lets him answer his own question of
	   2026-08-23: he can replace a 650px file with a 1300px one and it will occupy the same
	   space on screen at twice the pixel density instead of growing. Without it a bigger file
	   simply displays bigger, since the picture is otherwise shown at its own size. Measured
	   the same day: no gallery photograph in the archive is taller than 650px, so this changes
	   nothing about what is on the site today. */
	max-height: min(72vh, 650px);
	width: auto;
	height: auto;
	border: 1px solid var(--thumb-line);
	box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
}

/* Above the photograph, which is where his own photo pages have always printed it and what
   he asked for on 2026-08-21: over the picture the caption is certain to be on screen, under
   it a tall photograph can hide it. The colours here do not follow the gallery skin, because
   the lightbox overlay is dark whatever colour the page behind it is. */
.lightbox__caption {
	order: -1;
	color: #ffe9a8;
	text-align: center;
	max-width: 60ch;
	font-size: 1rem;
	line-height: 1.35;
	/* A caption slot that keeps its height whether the photograph has a caption or not: the
	   picture stays put as he pages through a gallery where only some are captioned. */
	min-height: 1.35em;
}

.lightbox__counter {
	color: #8fa9c2;
	font-size: 0.82rem;
}

.lightbox__button {
	position: absolute;
	background: rgba(255, 255, 255, 0.14);
	color: #fff;
	border: 1px solid rgba(255, 255, 255, 0.35);
	font-size: 1.6rem;
	line-height: 1;
	width: 46px;
	height: 46px;
	cursor: pointer;
	border-radius: 50%;
}

.lightbox__button:hover,
.lightbox__button:focus-visible {
	background: var(--accent);
	border-color: var(--accent);
	outline: none;
}

.lightbox__button--prev {
	left: 2vw;
	top: 50%;
	transform: translateY(-50%);
}

.lightbox__button--next {
	right: 2vw;
	top: 50%;
	transform: translateY(-50%);
}

/* Named, not a symbol: he asked on 2026-08-22 for the way back to say where it goes. It keeps
   the corner it had, so anyone who already learned the cross finds it in the same place. */
.lightbox__button--close {
	top: 2vh;
	right: 2vw;
	width: auto;
	height: auto;
	display: flex;
	align-items: center;
	padding: 9px 16px;
	border-radius: 3px;
	font-size: 0.95rem;
	font-weight: 700;
	font-family: inherit;
	background: var(--rail-home-bg);
	color: var(--rail-home-ink);
	border: 2px solid var(--thumb-line);
}

.lightbox__button--close:hover,
.lightbox__button--close:focus-visible {
	background: var(--thumb-line);
	border-color: var(--thumb-line);
	color: var(--rail-home-ink);
}

.site-footer {
	max-width: var(--column);
	margin: 0 auto 26px;
	padding: 0 clamp(16px, 3vw, 34px);
	color: var(--page-muted);
	font-size: 0.85rem;
}

/* A 122 px rail beside the photographs costs a fifth of a phone screen, so below this width
   it becomes a strip of buttons above them instead. */
@media (max-width: 720px) {
	.gallery-layout {
		flex-direction: column;
		gap: 16px;
	}

	/* The menu is above the photographs here, not beside them, so the rule that separates the
	   two turns with it: along the bottom instead of down the side. */
	.gallery-aside {
		flex: 1 1 auto;
		width: 100%;
		padding: 0 0 16px;
		border-right: 0;
		border-bottom: 2px solid var(--thumb-line);
	}

	/* Short and left-aligned here, not the 60% of the column it is beside the photographs:
	   at full width it would be a second line the same length as the border below the menu,
	   and two identical lines read as one of them being a mistake. */
	.gallery-aside__rule {
		width: 110px;
		margin: 0;
	}

	.gallery-maps {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: flex-start;
	}

	.gallery-map {
		max-width: 160px;
	}

	.gallery-rail__list {
		flex-direction: row;
		flex-wrap: wrap;
	}

	.gallery-rail__link {
		min-height: 0;
		padding: 7px 10px;
	}

	/* Whose buttons these are, said once over them. */
	.gallery-rail__caption {
		display: block;
		margin: 0 0 8px;
		color: var(--page-muted);
		font-size: 0.85rem;
	}

	/* Whose photographs these are, said again directly over them: the title at the top of the
	   page is 442 px behind by the time the grid starts. The count comes down with it, so the
	   lede at the top goes; on the index of galleries the lede has no replacement and stays. */
	.gallery-lede--gallery {
		display: none;
	}

	.gallery-grid-heading {
		display: block;
		margin: 4px 0 12px;
	}

	.gallery-grid-heading__title {
		display: block;
		color: var(--page-title);
		font-size: 1.15rem;
		line-height: 1.25;
	}

	.gallery-grid-heading__count {
		display: block;
		margin-top: 2px;
		color: var(--page-muted);
		font-size: 0.9rem;
	}
}

@media (max-width: 560px) {
	:root {
		/* Two thumbnails to a row on a 390 px screen, which is what his four-column table
		   collapses to anyway once the page is allowed to reflow. */
		--thumb-max: min(150px, 42vw);
	}

	.gallery-grid {
		gap: 10px;
	}

	.lightbox__button--prev,
	.lightbox__button--next {
		top: auto;
		bottom: 2vh;
		transform: none;
	}
}

/* ---------------------------------------------------------------------------
   HOME SKIN

   His home page is not his gallery pages, and the difference was measured with
   getComputedStyle on the live site rather than read off the markup: a sepia world map tiles
   behind everything, #FFCC66 is the navigation strip and nothing else, titles are maroon and
   descriptions #CC3300. An earlier draft took the palette from a grep for `bgcolor=` and made
   the navigation colour the background of the whole page.

   The map itself arrives as an inline rule from patoczka_home_background(), because its URL
   is an attachment address that differs between the local build, /staging and the live site.
   --------------------------------------------------------------------------- */

body.home {
	background-color: #f3ece1;
	background-repeat: repeat;
	color: #333;
}

/* The footer ink is set for the dark gallery skins, and the home page is the one light page on
   the site: #9fb6cc over the map measured 2.09:1, which is not readable text (measured
   2026-08-29 while the sheet over the map was coming off). It takes the page's own ink, 12.6:1,
   rather than a new colour. */
body.home .site-footer {
	color: inherit;
}

.home {
	max-width: var(--column);
	margin: 0 auto;
	padding: 0 16px 48px;
}

.home-heading {
	margin: 24px 0 0;
	padding-bottom: 14px;
	border-bottom: 1px solid var(--maroon);
	color: var(--maroon);
	font-weight: 600;
	text-align: center;
	line-height: 1.3;
}

/* His two font sizes in one line: the lead is set smaller than the title it introduces. */
.home-heading__lead {
	font-size: 1.05rem;
}

.home-heading__main {
	font-size: 1.6rem;
}

.home-nav {
	margin: 18px 0;
	background: var(--amber);
	border: 1px solid var(--maroon);
}

.home-nav__list {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 8px;
	margin: 0;
	padding: 6px 10px;
	list-style: none;
}

.home-nav__link {
	display: flex;
	align-items: center;
	gap: 8px;
	color: var(--maroon);
	font-size: 0.85rem;
	text-decoration: none;
}

.home-nav__link:hover,
.home-nav__link:focus-visible {
	color: #000;
	text-decoration: underline;
}

.home-nav__icon {
	flex: 0 0 auto;
	width: auto;
	height: 22px;
}

.home-grid {
	display: grid;
	/* minmax(0, 1fr), not 1fr: a long caption in one tile otherwise widens its column and the
	   whole grid stops fitting at 390 px. */
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 26px 22px;
	margin: 26px 0;
	padding: 0;
	list-style: none;
}

/* Picture on the left, title and description in their own column beside it: what his table
   cells LOOK like, measured rather than assumed. His icons are floated, and a float only keeps
   text out from under the picture while the text happens to be short enough. On his page it
   always is (0 lines below the icon across 48 cells at 1440 px). On ours the same float put
   text under the icon in 9 of 42 tiles, because our substitute font is larger than his Eras
   Demi ITC. A column cannot do that at any width or any length of description. */
.home-tile {
	min-width: 0;
	display: flex;
	align-items: flex-start;
	gap: 12px;
}

.home-tile__icon-link {
	flex: 0 0 auto;
	max-width: 45%;
	line-height: 0;
}

.home-tile__body {
	flex: 1 1 auto;
	min-width: 0;
}

.home-tile__icon {
	display: block;
	width: auto;
	max-width: 100%;
	max-height: 150px;
	margin: 2px 0 0;
}

.home-tile__link {
	color: var(--maroon);
	font-size: 1.15rem;
	text-decoration: none;
}

.home-tile__title {
	text-decoration: underline;
}

.home-tile__link:hover .home-tile__title,
.home-tile__link:focus-visible .home-tile__title {
	color: #000;
}

.home-tile__text {
	margin: 6px 0 0;
	color: var(--accent);
	font-size: 0.92rem;
	line-height: 1.45;
}

@media (max-width: 900px) {
	.home-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 600px) {
	.home-nav__list {
		grid-template-columns: minmax(0, 1fr);
	}

	/* Two tiles to a row on a phone, his request of 2026-08-28, in his own words "at a cost of
	   making things smaller": one column made the front page 7,662 px tall and he said it did
	   not look right. Two columns is also what his own page gives him when he pinches it down
	   far enough to see two, which is the comparison he made. The cost is real and it is paid
	   here: at 390 px a tile is 173 px wide, so the icon takes a third of it and the type comes
	   down with it. Below that the tile is a picture beside its text, as it is at every other
	   width and as his own table cells are. */
	.home-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 20px 10px;
	}

	/* Every pixel the page gives back goes to the description column, which is the part that
	   suffers from the second column: at 390 px the side padding was 16 px a side and the text
	   beside an icon had 107 px to wrap in. */
	.site-main {
		padding-left: 12px;
		padding-right: 12px;
	}

	/* One indent instead of three. WordPress puts `home` on the <body> of the front page and
	   the template puts it on the wrapper, so `.home { padding: 0 16px }` was being charged
	   twice with the 12 px of .site-main sitting between: 44 px a side out of 390, and a tile
	   146 px wide. Measured 2026-08-29. Both go, .site-main keeps the single indent, and the
	   tile becomes 178 px — which is where the larger icon and the wider description column
	   below are paid for. */
	.home {
		padding-left: 0;
		padding-right: 0;
		padding-bottom: 0;
	}

	/* Air above the title and under the lower bar, his notes of 2026-08-29, 21:15, both measured at
	   360 px, a little under the width his own phone gives the page. That width is read off his
	   screenshot two ways (checks/screenshot_viewport_width.py): the amber bar's 96 px against
	   the picture's scale, and the bar's width-to-height shape, which needs no scale at all.
	   Both land near 370, so 360 and 390 bracket his screen and the narrow pass is the stricter
	   of the two.

	   Above the title stood 64 px, and 52 of that was margin nobody looks at on a phone: 22 of
	   .site-main, 6 of its padding, 24 of the heading. Below the lower bar stood 140 px to the
	   copyright line, four bottom paddings stacked one on another: 18 under the bar, 48 under
	   the tile block, 34 inside .site-main and 40 below it. One of each is enough this narrow.
	   Scoped to the front page, because on a gallery page the same margin is the gap under the
	   site bar, and he asked for the galleries to be left alone. */
	body.home .site-main {
		margin-top: 8px;
		margin-bottom: 12px;
		padding-top: 0;
		padding-bottom: 0;
	}

	.home-tile {
		gap: 8px;
	}

	/* Tighter leading on the phone, his note of 2026-08-29. Both the heading and the tile
	   titles were inheriting the body's 1.55, which is set for paragraphs of running text; a
	   two-word gallery name that wraps onto a second line gets a gap that reads as a space
	   between tiles rather than inside one. The desktop keeps 1.3 / 1.55, where the lines are
	   long enough for that to be leading rather than air. */
	/* The rest of the air above the title, and the leading inside it. An <h1> with no font-size
	   of its own keeps the browser's 2em, and 2em of the body's 17 px is 34: this heading was
	   setting a 34 px strut under a 20.8 px title, so every line box in it came out 39.1 px
	   tall, 15 px more than the 23.9 the
	   stylesheet asks for, and half of that surplus sits above the first line. Letter #25 quoted
	   the stylesheet's number; he answered with what he could see. The heading now takes the
	   size it is actually printed at, so the strut and the letters are the same height. */
	.home-heading {
		margin-top: 12px;
		font-size: 1.3rem;
		line-height: 1.15;
	}

	/* The same mechanism one level down, and the same note of 2026-08-29, 21:15. The anchor asks for
	   1.2, but the column it sits in is a block of 17 px text at the body's 1.55, and a line box
	   is never shorter than its block's strut: 17 x 1.55 is 26.35, so a gallery name that wraps
	   was set 26.3 px a line,
	   not the 18.2 the rule below asks for. The column takes the title's own type. The
	   description carries its own size and leading and is untouched — he read it and said it
	   was fine. */
	.home-tile__body {
		font-size: 0.95rem;
		line-height: 1.2;
	}

	.home-tile__link {
		font-size: 0.95rem;
		line-height: 1.2;
	}

	.home-tile__text {
		margin-top: 4px;
		font-size: 0.72rem;
		line-height: 1.25;
	}

	.home-heading__main {
		font-size: 1.3rem;
	}

	/* The map across the whole screen, his note of 2026-08-29. What hid it was a near-opaque
	   sheet on the wrapper, and because the wrapper stops short of the screen edge the map
	   stayed visible in the side padding and nowhere else: exactly the "only on margins" he
	   described. The sheet becomes one even veil over the entire page, painted behind the
	   content, so the map reads everywhere including the margins.

	   0.55 is a measured number, not a round one. The descriptions are #CC3300 on a sepia map,
	   and over its darker coastlines that pair is the one at risk: bare map 3.91:1, veil 0.45
	   4.46:1, veil 0.55 4.58:1 against the 4.5 AA threshold, with the old sheet at 5.01:1 for
	   reference (checks/verify_home_phone_contrast.py, worst 5% of background pixels under the
	   text, positive control at full opacity). Desktop keeps the bare map, as his own page has
	   it and as he accepted on 2026-08-21. */
	body.home {
		position: relative;
	}

	body.home::before {
		content: '';
		position: absolute;
		inset: 0;
		background: rgba(255, 255, 255, 0.55);
		z-index: -1;
		pointer-events: none;
	}

	.home-tile__icon-link {
		/* 40% of a 178 px tile is 71 px, and 80 px is the narrowest icon file he has, so no
		   icon on the page is enlarged past its own pixels at this width. That is the
		   "technical limit on the pixels" he named himself on 2026-08-29. */
		max-width: 40%;
	}

	.home-tile__icon {
		max-height: 115px;
	}
}

/* ---------------------------------------------------------------------------
   CONTACT

   One column, wide enough to type a paragraph into and no wider. The trap field is
   moved out of sight rather than given display:none, because some bots skip fields
   they can tell are hidden and this one is meant to be filled in.
   --------------------------------------------------------------------------- */

.contact-form {
	max-width: 640px;
	margin: 18px 0 0;
}

.contact-form__field {
	margin: 0 0 16px;
}

.contact-form__field label {
	display: block;
	margin-bottom: 5px;
	color: var(--page-title);
	font-size: 0.95rem;
}

.contact-form__field input,
.contact-form__field textarea {
	width: 100%;
	padding: 9px 11px;
	font: inherit;
	color: var(--page-ink);
	background: var(--panel-bg);
	border: 1px solid var(--gold-soft);
	border-radius: 3px;
}

.contact-form__field textarea {
	resize: vertical;
}

.contact-form__field input:focus-visible,
.contact-form__field textarea:focus-visible {
	outline: 2px solid var(--link);
	outline-offset: 1px;
}

.contact-form__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.contact-form__actions button {
	padding: 9px 22px;
	font: inherit;
	color: var(--header-bg);
	background: var(--gold);
	border: 1px solid var(--gold-soft);
	border-radius: 3px;
	cursor: pointer;
}

.contact-form__actions button:hover,
.contact-form__actions button:focus-visible {
	background: var(--link-hover);
}

.contact-status {
	max-width: 640px;
	margin: 16px 0 0;
	padding: 10px 14px;
	border-left: 4px solid var(--gold);
	background: var(--panel-bg);
}

.contact-status--bad {
	border-left-color: var(--accent);
}
