/*
Theme Name: Fred Parhad 2
Theme URI: https://fredparhad.com/
Author: Built for Fred Parhad
Description: A quiet, full-screen portfolio theme for a bronze sculptor. The hand-drawn signature stands at the top left and the menu at the top right of every page; beneath them a cross-fading slideshow shows one sculpture at a time on plain cream. Includes a Sculptures post type that feeds both the slideshow and the gallery grid, per-piece caption fields, and colour and typography controls in the Customizer.
Version: 2.2.0
Requires at least: 6.0
Tested up to: 6.8
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: fred-parhad-2
Tags: portfolio, art, one-column, custom-colors, custom-menu, custom-logo, translation-ready, accessibility-ready
*/

/* ==========================================================================
   1. Fonts

   Josefin Sans is the theme face and is bundled locally (SIL Open Font
   License - see assets/fonts/JOSEFIN-SANS-LICENSE.txt). If you license the
   Adobe cut, "Josefin Sans Std", drop the webfont files into assets/fonts/
   and add a matching @font-face block below: the stack already prefers it.

   The other five families are the alternatives offered by the typography
   controls in the Customizer. Declaring a face costs nothing until a rule
   actually selects it - the browser only fetches the file then - so they sit
   here unused on a default install.
   ========================================================================== */

@font-face {
	font-family: "Josefin Sans";
	font-style: normal;
	font-weight: 100;
	font-display: swap;
	src: url("assets/fonts/josefin-sans-latin-100-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Josefin Sans";
	font-style: normal;
	font-weight: 200;
	font-display: swap;
	src: url("assets/fonts/josefin-sans-latin-200-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Josefin Sans";
	font-style: normal;
	font-weight: 300;
	font-display: swap;
	src: url("assets/fonts/josefin-sans-latin-300-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Josefin Sans";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/josefin-sans-latin-400-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Josefin Sans";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("assets/fonts/josefin-sans-latin-600-normal.woff2") format("woff2");
}

@font-face {
	font-family: "Cormorant Garamond";
	font-style: normal;
	font-weight: 300;
	font-display: swap;
	src: url("assets/fonts/cormorant-garamond-latin-300-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Cormorant Garamond";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/cormorant-garamond-latin-400-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Cormorant Garamond";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("assets/fonts/cormorant-garamond-latin-600-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Cormorant Garamond";
	font-style: italic;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/cormorant-garamond-latin-400-italic.woff2") format("woff2");
}

@font-face {
	font-family: "Lora";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/lora-latin-400-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Lora";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("assets/fonts/lora-latin-600-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Lora";
	font-style: italic;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/lora-latin-400-italic.woff2") format("woff2");
}

@font-face {
	font-family: "Playfair Display";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/playfair-display-latin-400-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Playfair Display";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("assets/fonts/playfair-display-latin-600-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Playfair Display";
	font-style: italic;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/playfair-display-latin-400-italic.woff2") format("woff2");
}

@font-face {
	font-family: "Jost";
	font-style: normal;
	font-weight: 300;
	font-display: swap;
	src: url("assets/fonts/jost-latin-300-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Jost";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/jost-latin-400-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Jost";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("assets/fonts/jost-latin-600-normal.woff2") format("woff2");
}
@font-face {
	font-family: "Jost";
	font-style: italic;
	font-weight: 400;
	font-display: swap;
	src: url("assets/fonts/jost-latin-400-italic.woff2") format("woff2");
}

/* Julius Sans One is drawn as a titling face and ships in one weight only.
   Every weight the theme asks for resolves to this single face, so text set
   in it reads at an even colour rather than switching between real cuts.
   Licence: assets/fonts/julius-sans-one-LICENSE.txt */
@font-face {
	font-family: "Julius Sans One";
	font-style: normal;
	font-weight: 100 700;
	font-display: swap;
	src: url("assets/fonts/julius-sans-one-latin-400-normal.woff2") format("woff2");
}

/* ==========================================================================
   2. Tokens

   --u is one "design pixel". The reference layouts were drawn at 1184x625,
   so at that window size --u resolves to 1px and the page matches them
   measurement for measurement. Everything in the composition is a multiple
   of --u, so the whole thing scales as one piece rather than drifting apart.
   ========================================================================== */

:root {
	--u: 1px; /* fallback for engines without min() */
	--u: clamp(0.8px, min(100vh / 625, 100vw / 1184), 1.4px);

	--cream: #fcfffa;
	/* The same colour at zero alpha, for the veil's fade. PHP overwrites this
	   from whatever background colour is set in the Customizer - see
	   fp2_rgba(). Ending a gradient on this rather than on the `transparent`
	   keyword keeps the hue constant all the way down. */
	--cream-0: rgba(252, 255, 250, 0);
	--ink: #0b0d21;
	--nav: #4c5678;
	--graphite: #6f6e69;
	--accent: #b77d00;

	/* The margins the signature and the menu stand in. The signature's left
	   edge and the last menu item's right edge sit on these. */
	--pad-l: calc(88 * var(--u));
	--pad-r: calc(86 * var(--u));

	/* The band the sculpture is drawn in. The picture is height-limited on
	   most windows, so this number is what a landscape sculpture actually
	   grows into; the vw cap is what keeps one off the very edge of a wide
	   window. */
	--stage-w: min(96vw, calc(1120 * var(--u)));

	/* How far out from the middle of the page each chevron sits, measured to
	   its outer edge. The two arrows are always this far from the centre, so
	   raising the number pushes them apart and lowering it draws them in.

	   A photograph wider than roughly 680u passes behind them; that matters
	   less than it used to, because on a pointer device the chevrons are
	   invisible until the pointer is inside their own box (see section 6).
	   If you upload panoramas and want them clear anyway, raise this towards
	   500u, which is the edge of the band above. */
	--arrow-reach: calc(340 * var(--u));

	/* How deep the soft edge under the sticky masthead runs. Taller is a
	   longer, gentler dissolve; shorter brings the picture back into focus
	   sooner. See section 5b. */
	--veil-h: calc(72 * var(--u));

	--fade: 900ms;
	--ease: cubic-bezier(0.4, 0, 0.2, 1);

	--font-ui: "Josefin Sans Std", "Josefin Sans", "Century Gothic", "Futura",
		"Trebuchet MS", sans-serif;

	/* One family, one size multiplier and one weight per controllable text
	   element. The Customizer overrides these; the size is a multiplier rather
	   than a fixed px value so the responsive clamps underneath keep working.

	   The weight values here are the theme's own light defaults - the "Theme
	   default" choice in the Customizer leaves them alone, and any other choice
	   writes a plain number (400/600/700) over the top. The bundled faces are
	   hinted at 300/400/600, so 700 draws as a synthesised bold on those and as
	   a true bold on Georgia and the system stack. */
	--fp-menu-font: var(--font-ui);
	--fp-menu-scale: 1;
	--fp-menu-weight: 200;
	--fp-title-font: var(--font-ui);
	--fp-title-scale: 1;
	--fp-title-weight: 200;
	--fp-body-font: var(--font-ui);
	--fp-body-scale: 1;
	--fp-body-weight: 300;
	--fp-gtitle-font: var(--font-ui);
	--fp-gtitle-scale: 1;
	--fp-gtitle-weight: 300;
	--fp-gdetails-font: var(--font-ui);
	--fp-gdetails-scale: 1;
	--fp-gdetails-weight: 200;
	--fp-gcaption-font: var(--font-ui);
	--fp-gcaption-scale: 1;
	--fp-gcaption-weight: 200;
}

@supports (height: 100dvh) {
	:root {
		--u: clamp(0.8px, min(100dvh / 625, 100vw / 1184), 1.4px);
	}
}

/* ==========================================================================
   3. Reset & base
   ========================================================================== */

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

html {
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--cream);
	color: var(--ink);
	font-family: var(--font-ui);
	font-weight: 300;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow-x: hidden;
}

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

a {
	color: var(--ink);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.22em;
	transition: color 220ms var(--ease);
}

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

:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 4px;
	border-radius: 2px;
}

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.skip-link {
	position: absolute;
	top: -100px;
	left: calc(var(--pad-l) + 12px);
	z-index: 100;
	padding: 10px 18px;
	background: var(--cream);
	border: 1px solid var(--ink);
	font-size: 15px;
	letter-spacing: 0.04em;
}

.skip-link:focus {
	top: 12px;
}

/* ==========================================================================
   4. Shell

   A plain column: the masthead across the top, then whatever the page is.
   The home page fills the window exactly; every other page grows past it and
   scrolls.
   ========================================================================== */

.site {
	position: relative;
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100dvh;
}

/* The pen-and-ink figure walking in off the bottom-left corner. Switched on
   under Appearance > Customize > Parhad theme; drawn on the home page and on
   the About and Contact templates.

   Fixed to the window rather than the page, so he holds the corner even where
   the page scrolls (About). Flush into the corner: left and bottom are both
   0, and the drawing itself already touches the left and bottom edges of its
   own viewBox, so there is no daylight between the ink and the corner.

   Sized at 63u: the previous theme drew him at 90u, and this is that less
   thirty per cent. Unless armed with tagged pictures he ignores the pointer,
   so he can never get between a visitor and a link. */
.walker {
	position: fixed;
	left: 0;
	bottom: 0;
	width: var(--walker-w, calc(63 * var(--u)));
	margin: 0;
	z-index: 1;
	pointer-events: none;
}

.walker img {
	display: block;
	width: 100%;
	height: auto;
}

/* Switched on and armed with tagged pictures, he is a real control: he takes
   the pointer, and sits above the pop overlay (z-index 90) so he stays
   clickable while a picture is showing - a second click steps to the next
   one. His corner is nowhere near the masthead or the slideshow arrows. See
   assets/js/walker.js. */
.walker--live {
	z-index: 100;
	pointer-events: auto;
}

.walker__btn {
	position: relative;
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
}

.walker__btn img {
	display: block;
	width: 100%;
	height: auto;
}

/* A larger touch target than the drawing itself, which on a phone is only a
   couple of dozen pixels wide. Grown only up and to the right, into the page:
   the figure is flush in the corner, so reaching past the left or bottom edge
   would only push the document out and give the page a stray scrollbar. */
.walker__btn::after {
	content: "";
	position: absolute;
	inset: calc(-20 * var(--u)) calc(-20 * var(--u)) 0 0;
}

.walker__btn:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 4px;
}

/* ==========================================================================
   5. Masthead: the signature at the left, the menu at the right

   The same on every page, home included. There is no second state to
   animate to, which is the whole of the difference from the previous theme.
   ========================================================================== */

.masthead {
	position: relative;
	z-index: 4;
	flex: 0 0 auto;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: calc(40 * var(--u));
	padding: calc(40 * var(--u)) var(--pad-r) 0 var(--pad-l);
	background: var(--cream);
}

.brand {
	display: block;
	flex: 0 1 auto;
	width: calc(460 * var(--u));
	max-width: 46%;
	line-height: 0;
}

.brand img,
.brand svg {
	display: block;
	width: 100%;
	height: auto;
}

/* Used only when there is no signature image and no custom logo. */
.brand.brand--text {
	font-size: calc(52 * var(--u));
	font-weight: 300;
	letter-spacing: 0.02em;
	line-height: 1.1;
	text-decoration: none;
}

.primary-nav {
	flex: 0 0 auto;
	/* Sets the first row of links against the upper half of the signature,
	   as in the reference layouts. */
	margin-top: calc(22 * var(--u));
}

/* Three columns of two, filled top to bottom then left to right - so the
   six default items land as

       Assyrian     Portraiture     About
       Figurative   Installations   Contact

   which is the arrangement in the reference layouts. A seventh item starts a
   fourth column rather than a third row, so the band keeps its height. */
.primary-nav ul {
	display: grid;
	grid-auto-flow: column;
	grid-template-rows: repeat(2, auto);
	grid-auto-columns: auto;
	justify-content: end;
	align-items: baseline;
	column-gap: calc(56 * var(--u));
	row-gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
}

.primary-nav a {
	display: inline-block;
	font-family: var(--fp-menu-font);
	font-size: calc(25 * var(--u) * var(--fp-menu-scale));
	font-weight: var(--fp-menu-weight);
	/* Small capitals: the labels are typed in title case and drawn with a
	   full-height initial over small caps, which is the lettering in the
	   reference layouts. Josefin Sans has no true small-cap glyphs, so the
	   browser synthesises them - hence the touch of tracking, which keeps the
	   scaled-down letters from crowding. */
	font-variant: small-caps;
	font-variant-caps: small-caps;
	letter-spacing: 0.015em;
	line-height: calc(36 * var(--u));
	color: var(--nav);
	text-decoration: none;
	white-space: nowrap;
}

.primary-nav a:hover,
.primary-nav a:focus-visible {
	color: var(--accent);
}

.primary-nav .current-menu-item > a,
.primary-nav .current_page_item > a {
	color: var(--accent);
}

/* The phone button. Hidden until the breakpoint in section 8 shows it. */
.nav-toggle {
	display: none;
	align-items: center;
	gap: 10px;
	padding: 6px 2px;
	background: none;
	border: 0;
	color: var(--nav);
	font-family: var(--fp-menu-font);
	font-size: 15px;
	font-variant: small-caps;
	font-variant-caps: small-caps;
	letter-spacing: 0.08em;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
	transition: color 220ms var(--ease);
}

.nav-toggle:hover,
.nav-toggle:focus-visible {
	color: var(--accent);
}

.nav-toggle__bars {
	display: block;
	width: 22px;
}

.nav-toggle__bars span {
	display: block;
	height: 1px;
	background: currentColor;
	transition: transform 220ms var(--ease), opacity 160ms linear;
}

.nav-toggle__bars span + span {
	margin-top: 6px;
}

/* The three bars fold into a cross while the panel is open. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) {
	transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) {
	opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) {
	transform: translateY(-7px) rotate(-45deg);
}

/* Open, the label drops away and only the cross is left; it comes back when
   the menu is closed. The cross is also nudged left of where the button sat. */
.nav-toggle[aria-expanded="true"] .nav-toggle__label {
	display: none;
}

.nav-toggle[aria-expanded="true"] {
	transform: translateX(-34px);
}

/* ==========================================================================
   6. Stage: the cross-fading sculpture slideshow

   Carried over from the previous theme without a change to the transition:
   the same 900ms opacity cross-fade on the same easing curve, the same
   visibility handling behind it, the same chevrons, and the same autoplay
   parameters (see assets/js/slideshow.js). Only the box it happens in has
   moved - it is centred under the masthead now instead of sitting in a
   column beside it.
   ========================================================================== */

/* No gap at the top: the picture starts on the masthead's own bottom edge, so
   an upright sculpture rises until it is level with the foot of the signature
   and the menu. It can never cross that line - the box it is drawn in starts
   there, and object-fit keeps the photograph inside the box - so the two can
   meet but not collide. Only a hair is left at the foot, enough that a
   sculpture is not standing on the very edge of the window. */
.stage {
	position: relative;
	z-index: 2;
	flex: 1 1 auto;
	min-width: 0;
	min-height: calc(210 * var(--u));
	padding: 0 0 calc(6 * var(--u));
}

/* Absolute rather than flex so the slides box always has a definite height -
   that is what lets each sculpture's max-height resolve against it. */
.slides {
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	width: var(--stage-w);
	top: 0;
	bottom: calc(6 * var(--u));
}

.slide {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: flex-end;
	justify-content: center;
	margin: 0;
	opacity: 0;
	visibility: hidden;
	transition: opacity var(--fade) var(--ease), visibility 0s linear var(--fade);
}

.slide.is-active {
	opacity: 1;
	visibility: visible;
	transition: opacity var(--fade) var(--ease), visibility 0s;
}

/* Fill the available box rather than holding a fixed drawn size, so a
   sculpture stays large when the window is narrowed. The 1.6x ceiling is the
   point where enlarging a photo past its own pixels starts to look soft;
   full-resolution uploads are effectively unbounded by it. */
.slide img {
	display: block;
	width: 100%;
	height: 100%;
	max-width: 100%;
	max-height: calc(var(--h, 462) * 1.6px);
	object-fit: contain;
	object-position: bottom center;
}

.slide figcaption {
	position: absolute;
	left: 50%;
	bottom: calc(-16 * var(--u));
	transform: translateX(-50%);
	font-size: calc(13 * var(--u));
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var(--graphite);
	white-space: nowrap;
}

/* --- the corner figure's pop -----------------------------------------------
   Click the drawn figure (when he is switched on and images are tagged
   Walker pictures) and walker.js fades one of those images in here for five
   seconds. Fixed and opaque, so it covers the whole window - masthead,
   slideshow, form, everything - on the home page and on About and Contact.
   Fade in is quick, fade out a little softer. See assets/js/walker.js.      */
.stage-pop {
	position: fixed;
	inset: 0;
	z-index: 90;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: clamp(24px, 7vh, 72px) clamp(24px, 7vw, 96px);
	background: var(--cream);
	opacity: 0;
	visibility: hidden;
	transition: opacity 1400ms var(--ease), visibility 0s linear 1400ms;
	pointer-events: none;
}

.stage-pop.is-visible {
	opacity: 1;
	visibility: visible;
	/* Catch the pointer while it is up, so a click cannot reach a link hidden
	   behind it. The figure sits above this (z-index 100) and stays live. */
	pointer-events: auto;
	transition: opacity 1000ms var(--ease), visibility 0s;
}

.stage-pop img {
	display: block;
	width: auto;
	height: auto;
	max-width: min(var(--stage-w), 100%);
	max-height: 100%;
	object-fit: contain;
}

/* --- arrows -------------------------------------------------------------
   Small plain chevrons that stay out of the way until the pointer is over
   the slideshow. They are held visible on touch screens, where there is no
   hover and hiding them would leave no way to change slides but the swipe.

   Pinned a fixed distance either side of the middle of the page rather than
   to the edges of the window, so they read as belonging to the sculpture
   instead of to the page. See --arrow-reach in section 2.                  */

.stage-arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 5;
	width: calc(26 * var(--u));
	height: calc(26 * var(--u));
	padding: 0;
	border: 0;
	background: none;
	color: var(--ink);
	cursor: pointer;
	opacity: 1;
	-webkit-tap-highlight-color: transparent;
	transition: opacity 260ms var(--ease), color 220ms var(--ease);
}

.stage-arrow svg {
	display: block;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

/* The invisible box around each chevron. It is both the hit area for a small
   target and - on a pointer device, see the hover block below - the only
   thing that brings the arrow into view, so it wants to be a comfortable
   size to find without being so big that it reaches into the sculpture. */
.stage-arrow::after {
	content: "";
	position: absolute;
	inset: calc(-42 * var(--u)) calc(-40 * var(--u));
}

.stage-arrow:hover,
.stage-arrow:focus-visible {
	color: var(--accent);
}

.stage-arrow--prev {
	left: calc(50% - var(--arrow-reach));
}

.stage-arrow--next {
	right: calc(50% - var(--arrow-reach));
}

.stage-arrow--next svg {
	transform: scaleX(-1);
}

@media (hover: hover) and (pointer: fine) {
	.stage-arrow {
		opacity: 0;
	}

	/* Shown only while the pointer is inside the arrow's own box - the
	   chevron plus the invisible margin around it set by .stage-arrow::after
	   above - or while an arrow has keyboard focus. Hovering the photograph
	   deliberately does nothing: the sculpture is left alone until someone
	   goes looking for the controls.

	   Deliberately NOT .stage:focus-within: a mouse click leaves the arrow
	   button focused, and :focus-within keys off plain :focus, so the arrows
	   would stay lit after the pointer had moved away - the "stuck visible"
	   bug. :focus-visible on the arrow itself covers the keyboard case
	   without that stickiness, since a mouse click does not match it. */
	.stage-arrow:hover,
	.stage-arrow:focus-visible {
		opacity: 1;
	}
}

/* ==========================================================================
   7. Interior pages
   ========================================================================== */

.page-body {
	position: relative;
	z-index: 2;
	flex: 1 1 auto;
	min-width: 0;
	width: 100%;
	max-width: calc(760 * var(--u));
	margin: 0;
	padding: calc(46 * var(--u)) var(--pad-r) calc(78 * var(--u)) var(--pad-l);
	font-family: var(--fp-body-font);
	font-size: calc(clamp(16px, calc(17 * var(--u)), 20px) * var(--fp-body-scale));
	font-weight: var(--fp-body-weight);
	line-height: 1.75;
}

.page-title {
	margin: 0 0 0.7em;
	font-family: var(--fp-title-font);
	font-size: calc(clamp(28px, calc(40 * var(--u)), 46px) * var(--fp-title-scale));
	font-weight: var(--fp-title-weight);
	letter-spacing: 0.03em;
	line-height: 1.1;
}

.page-body h2 {
	font-weight: var(--fp-body-weight);
	letter-spacing: 0.02em;
	margin-top: 1.8em;
}

.page-body img {
	height: auto;
}

/* The photograph at the top of a single sculpture or post. */
.entry-photo {
	margin: calc(26 * var(--u)) 0 calc(30 * var(--u));
}

.entry-photo img {
	display: block;
	width: 100%;
	height: auto;
}

.entry-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
	gap: calc(26 * var(--u));
	margin-top: calc(30 * var(--u));
	padding: 0;
	list-style: none;
}

.entry-grid figure {
	margin: 0;
}

.entry-grid img {
	display: block;
	width: 100%;
	height: auto;
}

.entry-grid figcaption {
	margin-top: 0.6em;
	font-size: 0.85em;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--graphite);
}


/* ==========================================================================
   7b. Gallery

   The sculpture grid, printed by the [fp2_gallery] shortcode. Three across,
   each photograph contained inside its frame rather than cropped to fill it,
   and set on the bottom edge of that frame - so a row of pieces stands on
   one line the way a shelf of them would, which is how the reference layout
   draws it.
   ========================================================================== */

/* The gallery template widens the body - the reading measure that suits a
   biography page would squeeze the grid to a single column. */
.page-body--wide {
	max-width: none;
}

.page-rule {
	height: 1px;
	margin: 0;
	background: rgba(11, 13, 33, 0.14);
}

/* The reference layout puts nothing between the menu and the first row of
   sculptures, so the gallery heading is taken off the page - kept in the
   markup, and kept as the page's one h1, for screen readers and search
   results. Delete this rule to have the title show over the grid again; it
   is centred, ready for that. */
.page-template-template-gallery .page-title {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
	text-align: center;
}

/* The rule under that heading goes with it. */
.page-template-template-gallery .page-rule {
	display: none;
}

/* The signature and menu used to hold still (position: sticky) while the
   page scrolled past them - removed per request. The masthead is back to
   being a normal part of the page flow on every page, so it scrolls out of
   view like anything else above the fold. */

/* ==========================================================================
   5b. The veil: removed per request - a picture now scrolls straight under
   the sticky masthead and is simply clipped at the header's edge rather
   than fading out. The markup (header.php's .masthead-veil and its four
   spans) is left in place since it is inert without this block; this one
   rule is what keeps it from ever painting.
   ========================================================================== */

.masthead-veil {
	display: none;
}

.fp-gallery {
	display: grid;
	/* Three across by default. An explicit count rather than auto-fill, so
	   the row reads the same on a laptop as on a wide monitor - the cards
	   grow instead of a fourth appearing. Two on tablets, one on phones. */
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: calc(112 * var(--u)) calc(40 * var(--u));
	margin: 0;
	padding: calc(56 * var(--u)) 0 calc(90 * var(--u));
}

.fp-piece {
	margin: 0;
}

/* No frame at rest: no border, no hairline shadow, and no tinted panel behind
   the picture - a cut-out PNG on a tint would still read as a box even with
   the border gone. The piece simply stands on the page, as it does in the
   slideshow. The lift on hover is all that remains.

   To put the mat back, restore:  background: #f7faf3;
   and to put the line back:      border: 1px solid rgba(11, 13, 33, 0.1); */
.fp-piece a {
	display: block;
	overflow: hidden;
	background: transparent;
	border: 0;
	transition: box-shadow 0.25s var(--ease);
}

.fp-piece a:hover,
.fp-piece a:focus-visible {
	box-shadow: 0 10px 26px rgba(11, 13, 33, 0.16);
}

/* A fixed 5:4 frame keeps the rows even; object-fit: contain grows every
   piece until whichever edge is the limiting one - top and bottom for an
   upright piece, left and right for a wide one - meets the frame. The bottom
   object-position then sets them all on the same line, so the plinths in a
   row agree with each other, as they do in the reference layout.

   Nothing scales on hover: with the photo already flush, any zoom would push
   its limiting edge past the frame and the overflow clip would shave the top
   of a head or the foot of a plinth. The frame itself answers the pointer
   instead, on .fp-piece a above. */
.fp-piece img {
	display: block;
	box-sizing: border-box;
	width: 100%;
	height: auto;
	aspect-ratio: 5 / 4;
	object-fit: contain;
	object-position: bottom center;
}

.fp-piece figcaption {
	margin-top: calc(22 * var(--u));
	text-align: center;
}

.fp-piece__title {
	display: block;
	font-family: var(--fp-gtitle-font);
	font-size: calc(clamp(12px, calc(13 * var(--u)), 15px) * var(--fp-gtitle-scale));
	font-weight: var(--fp-gtitle-weight);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ink);
	transition: color 220ms var(--ease);
}

.fp-piece a:hover + figcaption .fp-piece__title,
.fp-piece a:focus-visible + figcaption .fp-piece__title {
	color: var(--accent);
}

.fp-piece__details {
	display: block;
	margin-top: calc(3 * var(--u));
	font-family: var(--fp-gdetails-font);
	font-size: calc(clamp(13px, calc(15 * var(--u)), 17px) * var(--fp-gdetails-scale));
	font-style: italic;
	font-weight: var(--fp-gdetails-weight);
	letter-spacing: 0.01em;
	color: var(--graphite);
}

/* On a wide screen the grid shows the title and the date/material/size line
   only. The extra caption stays in the markup but is taken off the page,
   because Lightbox with PhotoSwipe builds its caption from this figcaption -
   delete the span and the text disappears from the viewer too.

   Clipped rather than display:none on purpose: a hidden element is skipped by
   some of the properties a plugin might read the text from, and clipping is
   read by all of them. The rule is scoped to .fp-gallery, so the copy the
   viewer makes - which lives inside .pswp, not in the grid - is untouched and
   shows normally.

   Section 8 puts the caption back on the page below 820px, where there is no
   hover to reward and opening the viewer costs a tap and a full-screen
   change of context. To show it at every width, delete this one rule. */
.fp-gallery .fp-piece__caption {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.fp-piece__caption {
	display: block;
	margin-top: 9px;
	font-family: var(--fp-gcaption-font);
	font-size: calc(clamp(13px, calc(14 * var(--u)), 16px) * var(--fp-gcaption-scale));
	font-weight: var(--fp-gcaption-weight);
	line-height: 1.6;
	color: var(--graphite);
}

/* Paragraphs within a caption - see fp2_gallery_shortcode(). Not scoped to
   .fp-gallery, so the spacing also holds in the lightbox, where the plugin
   copies this span (with its classes) into .pswp__dynamic-caption. */
.fp-piece__caption .fp-cap-p {
	display: block;
}

.fp-piece__caption .fp-cap-p + .fp-cap-p {
	margin-top: 0.7em;
}

/* ==========================================================================
   7e. Contact

   The studio photo, address and form are ordinary page content - normally a
   two-column Columns block - so the layout rules here just give that block
   some room and let [fp2_social_links] and [fp2_contact_form] (functions.php)
   read like a considered pair of columns rather than default block spacing.
   The honeypot field is not display:none (a filter that only hides that
   exact rule would defeat it) - it is pushed off-screen instead, which
   looks identical to a human and is still there for a script to fill in.
   ========================================================================== */

/* Trim the base .page-body's generous foot so the whole page - masthead,
   photo/form row, nothing else - fits inside one viewport height without a
   scrollbar. The copyright footer that used to sit here has been removed. */
.page-body--contact {
	padding-bottom: calc(10 * var(--u));
}

.page-body--contact .wp-block-columns {
	margin-top: calc(12 * var(--u));
	margin-bottom: 0;
	/* A wide channel between the photo column and the form, as in the
	   reference layout - the two halves read as separate rather than as one
	   block split down the middle. */
	gap: calc(104 * var(--u));
}

/* The photo's visible left edge is lined up with the start of the social-icon
   row beneath it, then it grows to the right - past the column, into the
   channel - so it reads a little larger than the column would allow. The
   image file carries a ~9px transparent deckle down its left side, so the
   -9px margin puts the picture itself (not its transparent border) on the
   line. */
.page-body--contact .contact-photo-bleed {
	width: calc((100% + 9px + 30 * var(--u)) * 0.95);
	/* -9px offsets the image's transparent left deckle; the further -40px
	   pulls the picture out into the page margin past the social row. Capped
	   to -1 * the page's own left padding so the pull can never exceed the
	   margin it is bleeding into - without the cap this pushed the photo
	   past the viewport edge (and got clipped) once the page margin shrank
	   below 49px at narrower desktop widths. */
	margin-left: max(-49px, -1 * var(--pad-l));
	/* Lift the photo clear of the form's top line - the social row below is
	   pinned to the foot of the column, so this only moves the picture. */
	margin-top: calc(-28 * var(--u) + 20px);
}

.page-body--contact .contact-photo-bleed img {
	display: block;
	width: 100%;
	height: auto;
}

@media (max-width: 781px) {
	/* Stacked layout: the photo stands on its own, full width. None of the
	   desktop bleed applies here - the -49px pull would push its top-left
	   corner off the screen even though there is room to centre it. */
	.page-body--contact .contact-photo-bleed {
		width: 100%;
		margin-left: 0;
		margin-top: 0;
	}

	/* Centre the social icons + address under the centred photo. */
	.contact-info-row {
		justify-content: center;
		text-align: center;
	}
}

.page-body--contact address {
	font-style: normal;
	margin: 0;
	color: var(--graphite);
	font-size: 1.25em;
	white-space: nowrap;
	/* Baseline nudge against the icons, in em so it scales with the
	   address's own (responsive) font-size instead of staying a fixed
	   amount while the text around it shrinks. */
	position: relative;
	top: -0.3em;
}

/* The photo column is the positioning context for the social row below - see
   the min-width rule under .contact-info-row. */
.page-body--contact .wp-block-column:first-child {
	position: relative;
}

/* Social icons and the address sit side by side on one line under the photo,
   icons first - matches the reference layout rather than stacking the
   address beneath the icons. Wraps only on the phone layout (section 8).

   The icon group and the address are one unit: the single scaling gap
   below is the only thing that sets the space between them, at every
   viewport width, so they keep the same relative position to each other
   as the window is resized instead of a fixed-pixel gap (fine on desktop)
   collapsing them together once --u shrinks on a narrow phone. */
.contact-info-row {
	display: flex;
	/* Icons centred on the cross axis, so they sit midway between the two
	   lines of the address rather than level with the first line. */
	align-items: center;
	flex-wrap: nowrap;
	gap: calc(34 * var(--u));
	margin-top: calc(24 * var(--u));
}

@media (min-width: 782px) {
	/* Drop the social row + address to the foot of the photo column, level
	   with the Send button at the foot of the form, instead of letting them
	   hang below it. The column stretches to the form's height, so bottom:0
	   lands the two on the same line. Below 782px the columns stack (WordPress
	   handles that at 781px) and this goes back into the normal flow. */
	.contact-info-row {
		position: absolute;
		/* Nudged 20px left of the column edge, into the page margin. */
		left: -20px;
		right: 20px;
		bottom: 0;
		margin-top: 0;
	}

	/* The form section shifted 50px right of its column, into the channel. */
	.page-body--contact .wp-block-column:last-child {
		position: relative;
		left: 50px;
	}

	/* Icons nudged 10px right, without moving the address. */
	.contact-social {
		position: relative;
		left: 10px;
	}
}

.contact-social {
	display: flex;
	gap: calc(18 * var(--u));
	margin: 0;
	padding: 0;
	list-style: none;
}

.contact-social a {
	display: block;
	color: var(--ink);
	opacity: 0.7;
	transition: opacity 200ms var(--ease);
}

.contact-social a:hover,
.contact-social a:focus-visible {
	opacity: 1;
}

.contact-social svg {
	width: calc(27 * var(--u));
	height: calc(27 * var(--u));
	min-width: 22px;
	min-height: 22px;
}

/* Name/Email/Subject stack in a narrower left column; Message sits beside
   them in a wider right column, tall enough to line up with the three
   fields it sits next to; Send sits under Message, right-aligned under it
   rather than under the short fields on the left. */
.contact-form {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
	gap: calc(20 * var(--u)) calc(48 * var(--u));
}

.contact-field {
	display: flex;
	flex-direction: column;
	gap: 0.4em;
}

.contact-field--name {
	grid-column: 1;
	grid-row: 1;
}

.contact-field--email {
	grid-column: 1;
	grid-row: 2;
}

.contact-field--subject {
	grid-column: 1;
	grid-row: 3;
}

.contact-field--message {
	grid-column: 2;
	grid-row: 1 / span 3;
}

.contact-field--message textarea {
	flex: 1 1 auto;
	min-height: calc(160 * var(--u));
}

@media (max-width: 720px) {
	.contact-form {
		grid-template-columns: minmax(0, 1fr);
	}

	/* Room is tight now - let the address drop under the icons again. */
	.contact-info-row {
		flex-wrap: wrap;
	}

	.contact-field--name,
	.contact-field--email,
	.contact-field--subject,
	.contact-field--message,
	.contact-submit {
		grid-column: 1;
	}

	.contact-field--name {
		grid-row: 1;
	}

	.contact-field--email {
		grid-row: 2;
	}

	.contact-field--subject {
		grid-row: 3;
	}

	.contact-field--message {
		grid-row: 4;
	}

	.contact-submit {
		grid-row: 5;
	}
}

.contact-field label {
	font-size: 0.85em;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--graphite);
}

.contact-field input,
.contact-field textarea {
	font: inherit;
	color: var(--ink);
	background: transparent;
	border: 0;
	border-bottom: 1px solid rgba(11, 13, 33, 0.3);
	padding: 0.4em 0.1em;
	resize: vertical;
}

.contact-field input:focus-visible,
.contact-field textarea:focus-visible {
	outline: none;
	border-bottom-color: var(--accent);
}

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

.contact-submit {
	grid-column: 2;
	justify-self: end;
	margin-top: 0.6em;
	padding: 0.8em 2.2em;
	font: inherit;
	font-size: 0.85em;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--cream);
	background: var(--ink);
	border: 0;
	cursor: pointer;
	transition: background 200ms var(--ease);
}

.contact-submit:hover,
.contact-submit:focus-visible {
	background: var(--accent);
}

.contact-notice {
	margin: 0 0 1.6em;
	padding: 0.9em 1.2em;
	border-left: 3px solid var(--accent);
	background: rgba(183, 125, 0, 0.08);
}

.contact-notice--error {
	border-left-color: #a33;
	background: rgba(170, 51, 51, 0.08);
}

@media (max-width: 720px) {
	.contact-form {
		max-width: none;
	}

	/* This rule sits after the .contact-submit base block above, so it is the
	   one that lands the button in the single column - the earlier
	   max-width:720 block loses to that base rule on source order. */
	.contact-submit {
		grid-column: 1;
		justify-self: end;
	}
}

/* ==========================================================================
   8. Tablets and phones

   The masthead keeps its shape - signature left, menu right - down to the
   tablet breakpoint. Below that the menu folds behind a button, because six
   small-cap labels in three columns will not sit beside the signature on a
   phone without shrinking past reading size.
   ========================================================================== */

@media (max-width: 1100px) {
	:root {
		--pad-l: calc(48 * var(--u));
		--pad-r: calc(48 * var(--u));
		--stage-w: min(94vw, calc(860 * var(--u)));
	}

	.primary-nav ul {
		column-gap: calc(38 * var(--u));
	}
}

@media (max-width: 820px) {
	:root {
		--u: clamp(0.9px, min(100vw / 620, 100vh / 900), 1.5px);
		--pad-l: 22px;
		--pad-r: 22px;
		--stage-w: 100%;
		--walker-w: clamp(22px, 6.3vw, 36px);
	}

	/* Only pull the picture in for the drawn figure when he is switched on,
	   so a site without him keeps the full width. */
	.show-walker {
		--stage-w: calc(100% - 2 * (var(--walker-w) + clamp(8px, 2.4vw, 14px)));
	}

	.masthead {
		align-items: center;
		/* Wraps so that without scripting - where the panel below stays in
		   the flow rather than becoming a dropdown - the menu drops to its
		   own line under the signature instead of squeezing beside it. */
		flex-wrap: wrap;
		gap: 16px;
		padding: 20px var(--pad-r) 14px var(--pad-l);
	}

	.brand {
		width: 260px;
		max-width: 62%;
	}

	.js .nav-toggle {
		display: inline-flex;
		/* Pinned to the top of the masthead line by a fixed offset, not to the
		   foot of the signature - the signature grows taller above the tablet
		   breakpoint, and a flex-end button would drop with it. flex-start
		   keeps the button at the same height whatever the signature does. */
		align-self: flex-start;
		margin-top: 12px;
	}

	/* Closed, the menu is out of the flow behind the button. Open, it is laid
	   over the masthead's right side without taking any space - the page below
	   does not move. No background or shadow: it reads as part of the header,
	   the way it does on a wide screen. Without scripting it is shown for good
	   - a button that cannot be pressed must not be the only way in.

	   top:80px drops it clear of the signature on a narrow screen; above 485px,
	   where the two columns clear the signature, a rule after this block lifts
	   it up beside the signature (the reference placement). */
	.js .primary-nav {
		display: none;
		position: absolute;
		top: 80px;
		right: var(--pad-r);
		z-index: 5;
		/* The panel overlays the button and the top of the page. Only the
		   links themselves take clicks (see .primary-nav a below); everything
		   between them stays click-through, so the X underneath still closes
		   the menu and the page behind is still reachable. */
		pointer-events: none;
	}

	.js .primary-nav.is-open {
		display: block;
	}

	.primary-nav {
		margin-top: 0;
	}

	/* Two columns held to the right: the four section links stacked down the
	   first, About and Contact at the foot of the second - the arrangement in
	   the reference. */
	.primary-nav ul {
		grid-auto-flow: column;
		grid-template-rows: repeat(4, auto);
		grid-template-columns: none;
		grid-auto-columns: max-content;
		justify-content: end;
		column-gap: calc(34 * var(--u));
		row-gap: 2px;
	}

	.primary-nav li:nth-last-child(2) {
		grid-row: 3;
	}

	.primary-nav li:nth-last-child(1) {
		grid-row: 4;
	}

	/* Menu items set to match the "Menu" button label (.nav-toggle, 15px). */
	.primary-nav a {
		font-size: 15px;
		line-height: 1.5;
		pointer-events: auto;
	}

	.stage {
		padding: 10px 0 22px;
	}

	.slides {
		top: 10px;
		bottom: 22px;
	}

	/* On a phone the picture wants the whole width, so the 1.6x ceiling that
	   keeps a small photograph from being enlarged past its own pixels is the
	   only limit that should still apply. */
	.slide img {
		max-height: 100%;
	}

	/* The stage runs nearly the full height of the window here, so an upright
	   sculpture standing on its bottom edge still reads well. A landscape one
	   only fills the width, leaving a tall band of empty space above it - so
	   those sit centred in the stage instead. */
	.slide--wide {
		align-items: center;
	}

	.slide--wide img {
		object-position: center;
	}

	.stage-arrow {
		width: 24px;
		height: 24px;
	}

	.stage-arrow--prev {
		left: 10px;
	}

	.stage-arrow--next {
		right: 10px;
	}

	.page-body {
		max-width: none;
		padding: 26px var(--pad-r) 54px var(--pad-l);
	}

	.fp-gallery {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 40px 26px;
		padding: 30px 0 60px;
	}

	/* The caption goes back on the page here. It is clipped on a wide screen
	   (section 7b) because the lightbox is one hover and one click away; on a
	   phone that is a tap and a full-screen change of context, so the text
	   about the piece belongs under the piece.

	   Every property the clip set has to be given back explicitly - margin
	   included, which the clip had at -1px. */
	.fp-gallery .fp-piece__caption {
		position: static;
		width: auto;
		height: auto;
		margin: 10px auto 0;
		padding: 0;
		overflow: visible;
		clip: auto;
		clip-path: none;
		white-space: normal;
		/* A caption sets its own measure rather than running the full width
		   of a one-column grid, which would be a very long line to read. */
		max-width: 42ch;
		font-size: calc(14px * var(--fp-gcaption-scale));
		line-height: 1.65;
		text-wrap: pretty;
		/* Justified, with hyphenation on so the narrow measure does not open
		   up rivers of white space between the words. */
		text-align: justify;
		-webkit-hyphens: auto;
		hyphens: auto;
	}
}

/* Wide enough that the menu's two columns clear the signature: lift the open
   menu up so it sits beside the signature, filling the space to its right,
   rather than below the button. Below this the columns would land on top of
   the signature, so there it stays put. */
@media (min-width: 485px) and (max-width: 820px) {
	.js .primary-nav {
		top: 16px;
	}
}

@media (max-width: 520px) {
	.brand {
		width: 210px;
	}

	.fp-gallery {
		grid-template-columns: minmax(0, 1fr);
		gap: 34px;
	}

	.fp-piece img {
		aspect-ratio: 4 / 3;
	}
}

/* Short landscape phones - claw back vertical space so the sculpture is not
   squeezed between the masthead and the bottom of the window. */
@media (max-height: 480px) and (orientation: landscape) {
	.masthead {
		padding-top: 10px;
		padding-bottom: 8px;
	}

	.brand {
		width: 190px;
	}

	.stage {
		padding: 6px 0 12px;
	}

	.slides {
		top: 6px;
		bottom: 12px;
	}

	/* No room for him down here, and the sculpture needs every pixel. */
	.walker,
	.stage-pop {
		display: none;
	}

	.show-walker {
		--stage-w: 100%;
	}
}

/* ==========================================================================
   9. Motion and print
   ========================================================================== */

@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;
	}

	/* The cross-fade is the one thing that must not become a 0.01ms flash:
	   visibility rides on the same shorthand, so cutting the duration to
	   nothing would swap the pictures instantly and hard. Autoplay is already
	   off for these visitors (see assets/js/slideshow.js), so this only
	   applies to a deliberate press of an arrow. */
	.slide,
	.slide.is-active {
		transition-duration: 220ms !important;
	}
}

@media print {
	.masthead,
	.stage-arrow,
	.nav-toggle,
	.skip-link {
		display: none !important;
	}

	body {
		background: #fff;
		color: #000;
	}

	.slide {
		position: static;
		opacity: 1;
		visibility: visible;
	}
}

/* ==========================================================================
   10. WordPress core classes the editor can emit
   ========================================================================== */

.alignleft {
	float: left;
	margin: 0.4em 1.6em 1em 0;
}

.alignright {
	float: right;
	margin: 0.4em 0 1em 1.6em;
}

.aligncenter {
	display: block;
	margin-left: auto;
	margin-right: auto;
}

.wp-caption,
.gallery-caption {
	max-width: 100%;
	font-size: 0.86em;
	color: var(--graphite);
}

.sticky,
.bypostauthor {
	/* Declared so a theme check for these classes passes. */
	display: block;
}

/* ==========================================================================
   11. About page

   The biography is ordinary content now - Paragraph blocks and, wherever a
   photo of Fred belongs, a native Media & Text block (its own "flip" option
   is what alternates which side the picture falls on, not custom CSS here).
   This section only adds two things Gutenberg doesn't: each Media & Text
   block dissolves upward into place as it crosses the middle of the screen,
   and its photograph gets a blurred, fading edge. Both are driven by
   assets/js/reveal.js, which finds every .wp-block-media-text on this
   template and adds the classes this CSS reacts to - the img's own URL is
   read from the DOM and written to --photo-url there too, since a
   pseudo-element cannot read an <img>'s src directly.
   ========================================================================== */

.page-body--about .wp-block-media-text {
	margin: calc(64 * var(--u)) 0;
	align-items: center;
}

.page-body--about .wp-block-media-text__media {
	position: relative;
	margin: 0;
	isolation: isolate;
}

/* The photo keeps its rectangle - only the outer band along each of its four
   sides fades. Two things happen in that band, same idea as the masthead
   veil that used to run under the header: a blurred, slightly enlarged copy
   of the photo shows through as the sharp one fades out over it, then that
   blurred copy fades to nothing right at the true edge.

   Both masks are two linear gradients (one per axis) combined with
   mask-composite: intersect, so a pixel only survives if it is unfaded on
   *both* axes - which is what keeps the fade following the straight edges
   and corners instead of rounding them off into an oval. */
.page-body--about .wp-block-media-text__media::before {
	content: "";
	position: absolute;
	inset: -4%;
	z-index: 0;
	background-image: var(--photo-url);
	background-size: cover;
	background-position: center;
	filter: blur(11px);
	-webkit-mask-image: linear-gradient(to right, transparent 0%, transparent 5%, black 13%, black 87%, transparent 95%, transparent 100%),
		linear-gradient(to bottom, transparent 0%, transparent 5%, black 13%, black 87%, transparent 95%, transparent 100%);
	mask-image: linear-gradient(to right, transparent 0%, transparent 5%, black 13%, black 87%, transparent 95%, transparent 100%),
		linear-gradient(to bottom, transparent 0%, transparent 5%, black 13%, black 87%, transparent 95%, transparent 100%);
	-webkit-mask-composite: source-in;
	mask-composite: intersect;
	pointer-events: none;
}

.page-body--about .wp-block-media-text__media img {
	position: relative;
	z-index: 1;
	display: block;
	width: 100%;
	height: auto;
	margin: 0;
	-webkit-mask-image: linear-gradient(to right, transparent 0%, black 8%, black 92%, transparent 100%),
		linear-gradient(to bottom, transparent 0%, black 8%, black 92%, transparent 100%);
	mask-image: linear-gradient(to right, transparent 0%, black 8%, black 92%, transparent 100%),
		linear-gradient(to bottom, transparent 0%, black 8%, black 92%, transparent 100%);
	-webkit-mask-composite: source-in;
	mask-composite: intersect;
}

.reveal {
	opacity: 0;
	transform: translateY(calc(18 * var(--u)));
	transition: opacity 0.7s ease, transform 0.7s ease;
}

.reveal.is-visible {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.reveal {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* The title and the hairline under it are dropped from the About page - kept
   in the markup (screen-reader-text) for search engines and screen readers,
   which is the same trick .page-template-template-gallery uses on its own
   heading, but taken off the page here rather than shown. */
.page-template-template-about .page-title,
.page-template-template-about .page-rule,
.page-template-template-installations .page-title,
.page-template-template-installations .page-rule,
.page-template-template-contact .page-title,
.page-template-template-contact .page-rule {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* page-body has no auto margins of its own - every other interior page sits
   under the masthead's left padding instead of centred, which is the
   reference layout everywhere else. About is the one page asked to centre
   its column, so the margin is added here rather than on .page-body itself. */
.page-body--about {
	/* 25% wider than the theme's normal 760u reading column. */
	max-width: calc(950 * var(--u));
	margin-left: auto;
	margin-right: auto;
	/* More air under the signature/menu than the theme's normal 46u - the
	   About column starts further down the page instead of crowding the
	   masthead. */
	padding-top: calc(120 * var(--u));
}

/* Every paragraph on the page - the opening line and the four beside the
   photos - reads at the same size, set here rather than left at the
   theme's normal body size. */
.page-body--about .entry-content p {
	font-size: calc(clamp(19px, calc(21 * var(--u)), 25px) * var(--fp-body-scale));
	line-height: 1.65;
}

/* The opening line stands alone, above the photo pairs - no image of its
   own, so it just wants space below it before the first photo begins. */
.page-body--about .entry-content > .about-intro {
	margin: 0 0 calc(50 * var(--u));
}

/* ==========================================================================
   12. Wide-page content width

   page-body--wide also covers the gallery template (a fixed three-across
   grid, not a block-editor page), so all three rules below are scoped to
   page-body--installations/page-body--contact specifically - Installations
   and Contact drop the reading-width cap so a Gallery or Columns block can
   run wider than a paragraph comfortably would. Every direct child of the
   content keeps a normal reading measure by default; a block given
   WordPress's own "wide" or "full" alignment - the toolbar option above any
   image, gallery or columns block - is what opens it up. This is the
   theme-side half of add_theme_support('align-wide'), already declared in
   functions.php.
   ========================================================================== */

.page-body--installations .entry-content > *,
.page-body--contact .entry-content > * {
	max-width: calc(760 * var(--u));
	margin-left: auto;
	margin-right: auto;
}

.page-body--installations .entry-content > .alignwide,
.page-body--contact .entry-content > .alignwide {
	max-width: calc(1040 * var(--u));
}

.page-body--installations .entry-content > .alignfull,
.page-body--contact .entry-content > .alignfull {
	max-width: none;
}

/* Installations keeps its photos and galleries to the reading measure - the
   same width as the paragraphs above them - rather than letting a wide or
   full alignment run them out past the text. Later than the two rules above
   and at the same weight, so it wins for this page only; Contact still opens
   up on wide/full. */
.page-body--installations .entry-content > .alignwide,
.page-body--installations .entry-content > .alignfull {
	max-width: calc(760 * var(--u));
}

.page-body--installations .page-title,
.page-body--installations .page-rule {
	max-width: calc(760 * var(--u));
}

/* More air under the signature/menu than the theme's normal 46u, matching
   the same treatment given to the About column. */
.page-body--installations {
	padding-top: calc(120 * var(--u));
}

/* ==========================================================================
   13. Installations

   A public monument gets more room than a gallery tile: a heading, a place
   and date line, the story in full paragraphs, and its photographs - all
   ordinary content, edited the normal way. This section styles the one
   piece Gutenberg has no button for (the italic place/date line - add the
   "installation-meta" class to that paragraph from the block's Advanced
   panel) and gives the Separator block between one monument and the next a
   little more air.
   ========================================================================== */

.page-body--installations .entry-content h2 {
	margin: calc(64 * var(--u)) auto 0.2em;
	font-family: var(--fp-title-font);
	font-size: calc(clamp(22px, calc(28 * var(--u)), 32px) * var(--fp-title-scale));
	font-weight: var(--fp-body-weight);
	letter-spacing: 0.02em;
}

.page-body--installations .entry-content h2:first-child {
	margin-top: 0;
}

.page-body--installations .entry-content .installation-meta {
	margin-bottom: 1.4em;
	font-style: italic;
	color: var(--graphite);
}

.page-body--installations .entry-content hr.wp-block-separator {
	max-width: calc(760 * var(--u));
	margin: calc(56 * var(--u)) auto;
}
