/* =========================================================================
   Polina Zueva — theme stylesheet
   Tokens and components follow "Design System and WordPress Map" exactly.
   Sections alternate between --pz-bg and --pz-bg-alt; never a third ground.
   ========================================================================= */

/* -- typeface ------------------------------------------------------------
   Bodoni Moda and Inter, self-hosted.

   They used to come from fonts.googleapis.com, which cost a render-blocking
   stylesheet on a third-party origin before a single glyph could even be
   requested — 805ms of the mobile First Contentful Paint, measured. Declaring
   the faces here costs nothing extra: the browser already has to parse this
   file, and the fonts now come off the same connection as everything else.

   Both families are variable fonts, so one file covers the whole weight range
   and the `font-weight: 400 500` ranges below are interpolated rather than
   snapped. The unicode-range blocks are Google's own, kept so a page of plain
   English never downloads the latin-ext file.
   ------------------------------------------------------------------------ */

@font-face {
	font-family: 'Bodoni Moda';
	font-style: normal;
	font-weight: 400 500;
	font-display: swap;
	src: url('../fonts/bodoni-moda-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Bodoni Moda';
	font-style: normal;
	font-weight: 400 500;
	font-display: swap;
	src: url('../fonts/bodoni-moda-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: 'Bodoni Moda';
	font-style: italic;
	font-weight: 400;
	font-display: swap;
	src: url('../fonts/bodoni-moda-italic-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Bodoni Moda';
	font-style: italic;
	font-weight: 400;
	font-display: swap;
	src: url('../fonts/bodoni-moda-italic-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 300 600;
	font-display: swap;
	src: url('../fonts/inter-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 300 600;
	font-display: swap;
	src: url('../fonts/inter-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
	--pz-bg: #0B0B0C;
	--pz-bg-alt: #101011;
	--pz-surface: #151516;
	--pz-text: #EDE9E3;
	--pz-text-2: #B8B2AA;
	--pz-muted: #8E8A83;
	/*
	 * The bottom of the grey ramp, set by contrast rather than by eye.
	 *
	 * --pz-faint was #7E7972, which reads 4.56:1 on --pz-bg but only 4.23:1 on
	 * --pz-surface, where the purchase block's dt row and the testimonial card's
	 * meta line actually sit. --pz-fainter was #5F5B56 — 2.92:1, well under the
	 * line anywhere. Both carry 11px text, so both need 4.5:1.
	 *
	 * The ramp cannot hold four rungs and keep the bottom two legible, so it now
	 * holds three: 5.73 / 5.01 / 4.54 on --pz-bg. The steps are narrower than
	 * they were, which is the cost of every one of them being readable.
	 *
	 * --pz-fainter is measured against --pz-bg alone — the footer legal strip is
	 * the only place it is used and the footer is never the alternate ground. It
	 * would need to be lighter than --pz-faint to clear 4.5:1 on --pz-surface,
	 * which would invert the ramp, so keep it off that ground.
	 */
	--pz-faint: #848079;   /* 5.01 on bg · 4.84 on alt · 4.64 on surface */
	--pz-fainter: #7C7974; /* 4.54 on bg — footer legal strip only */
	--pz-gold: #C8A15A;
	--pz-gold-light: #E3C88F;
	--pz-hairline: rgba(237, 233, 227, .09);
	/*
	 * Two different jobs, and only one of them has a contrast floor.
	 *
	 * --pz-hairline rules off sections. It is decoration, WCAG exempts it, and
	 * it stays as faint as it was drawn.
	 *
	 * --pz-hairline-strong is the visible edge of controls — the chip borders,
	 * the underline beneath every form field, the lightbox buttons. A text input
	 * with a transparent background *is* that underline: remove it and there is
	 * nothing on screen to say a field is there. SC 1.4.11 asks 3:1 for that and
	 * .28 gave 2.20, so it moves to .38, which clears 3:1 on all three grounds
	 * (3.11 on bg, 3.15 on alt, 3.17 on surface).
	 */
	--pz-hairline-strong: rgba(237, 233, 227, .38);

	--pz-serif: 'Bodoni Moda', 'Didot', Georgia, serif;
	--pz-sans: 'Inter', system-ui, -apple-system, sans-serif;

	--pz-container: 1440px;
	--pz-gutter: clamp(20px, 4vw, 56px);
	--pz-section: clamp(64px, 9vw, 130px);
	--pz-grid-gap: clamp(18px, 2.4vw, 34px);
}

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

/* The hidden attribute has to beat component display rules. A card set to
   display:flex ignores the browser default for [hidden], so filtering set
   the attribute and nothing moved. */
[hidden] { display: none !important; }

/* The header is fixed, so an anchor jump has to stop short of it or the
   section heading lands underneath the bar. This matters most for the
   "load more" links, which are full reloads onto #workshops while images
   are still settling. 96px clears the 72px mobile bar and the 68px
   scrolled desktop one with room to spare. */
html { scroll-behavior: smooth; scroll-padding-top: 96px; }

body {
	margin: 0;
	background: var(--pz-bg);
	color: var(--pz-text);
	font-family: var(--pz-sans);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.75;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

img, video { display: block; max-width: 100%; height: auto; }
a { color: var(--pz-gold); text-decoration: none; transition: color .25s ease; }
a:hover { color: var(--pz-gold-light); }
::selection { background: rgba(200, 161, 90, .28); color: #fff; }
:focus-visible { outline: 2px solid var(--pz-gold); outline-offset: 3px; }

/* Every photograph on the site takes the same treatment — no exceptions. */
.pz-photo { filter: grayscale(1) contrast(1.05); }

/* -- typography ---------------------------------------------------------- */

h1, h2, h3, h4 { font-family: var(--pz-serif); font-weight: 400; margin: 0 0 .5em; }
h1 { font-size: clamp(40px, 6.4vw, 92px); line-height: 1; letter-spacing: -.015em; }
h2 { font-size: clamp(28px, 4vw, 58px); line-height: 1.05; }
h3 { font-size: clamp(21px, 1.9vw, 26px); line-height: 1.15; }
h4 { font-size: 19px; line-height: 1.2; }
p { margin: 0 0 1em; }
em { font-style: italic; color: var(--pz-gold-light); }

.pz-lead { font-size: 16px; line-height: 1.75; color: var(--pz-text-2); max-width: 56ch; }
.pz-small { font-size: 14px; line-height: 1.65; color: var(--pz-muted); }
.pz-measure { max-width: 62ch; }

/* Family and line-height are stated rather than inherited so this looks the
   same on a <p> and on an <h2>. Some of these labels are decoration and some
   are genuinely the heading of their section — single-course.php's "Overview"
   is the heading the course body hangs off — and which element carries the
   class should be a question about the outline, not about the type. */
.pz-eyebrow {
	display: flex;
	align-items: center;
	gap: 14px;
	font-family: var(--pz-sans);
	font-size: 11px;
	font-weight: 400;
	line-height: 1.75;
	letter-spacing: .28em;
	text-transform: uppercase;
	color: var(--pz-gold);
	margin-bottom: 24px;
}
.pz-eyebrow::before { content: ''; width: 32px; height: 1px; background: var(--pz-gold); flex: none; }
.pz-eyebrow--wide::before { width: 44px; }
.pz-eyebrow--center { justify-content: center; }

.pz-quote {
	font-family: var(--pz-serif);
	font-style: italic;
	font-size: clamp(22px, 2.9vw, 38px);
	line-height: 1.4;
	margin: 0;
}

/* -- layout -------------------------------------------------------------- */

.pz-container { max-width: var(--pz-container); margin: 0 auto; padding-inline: var(--pz-gutter); }
.pz-section { padding-block: var(--pz-section); }
.pz-section--alt { background: var(--pz-bg-alt); border-top: 1px solid var(--pz-hairline); }
.pz-section--ruled { border-top: 1px solid var(--pz-hairline); }

.pz-split {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: clamp(40px, 6vw, 90px);
	align-items: center;
}

/* Asymmetric two-column layouts: content beside a panel, or image beside copy.
   Both collapse to a single column at the nav breakpoint. */
.pz-two-col { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: clamp(40px, 6vw, 90px); align-items: start; }
.pz-two-col--instructor { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); align-items: center; }
@media (max-width: 999px) {
	.pz-two-col,
	.pz-two-col--instructor { grid-template-columns: 1fr; }
}

.pz-section-head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 28px;
	margin-bottom: clamp(40px, 5vw, 72px);
}
.pz-section-head p { max-width: 38ch; margin: 0; color: var(--pz-muted); font-size: 15px; line-height: 1.7; }

/* Hairline grids: gap 1px plus a per-cell outline. Never a container background. */
.pz-hairline-grid { display: grid; gap: 1px; }
.pz-hairline-grid > * { outline: 1px solid var(--pz-hairline); background: var(--pz-bg); }
.pz-section--alt .pz-hairline-grid > * { background: var(--pz-bg-alt); }

/* -- buttons ------------------------------------------------------------- */

.pz-btn {
	display: inline-block;
	background: transparent;
	font-family: var(--pz-sans);
	font-weight: 400;
	font-size: 12px;
	letter-spacing: .2em;
	text-transform: uppercase;
	padding: 17px 36px;
	border: 1px solid transparent;
	cursor: pointer;
	transition: background .25s ease, border-color .25s ease, color .25s ease;
}
.pz-btn--primary { background: var(--pz-gold); color: var(--pz-bg); }
.pz-btn--primary:hover { background: var(--pz-gold-light); color: var(--pz-bg); }
.pz-btn--secondary { color: var(--pz-text); border-color: var(--pz-hairline-strong); }
.pz-btn--secondary:hover { border-color: var(--pz-gold); background: rgba(200, 161, 90, .08); color: var(--pz-text); }
.pz-btn--ghost { color: var(--pz-gold-light); border-color: rgba(200, 161, 90, .55); }
.pz-btn--ghost:hover { background: rgba(200, 161, 90, .12); border-color: var(--pz-gold); }
.pz-btn--block { display: block; width: 100%; text-align: center; }

.pz-link-arrow {
	display: inline-block;
	font-size: 12px;
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--pz-gold-light);
	border-bottom: 1px solid rgba(200, 161, 90, .45);
	padding-bottom: 6px;
}
.pz-link-arrow:hover { border-color: var(--pz-gold); }

.pz-actions { display: flex; flex-wrap: wrap; gap: 14px; }
.pz-actions--center { justify-content: center; }

/* Social links as buttons. The footer keeps its muted text treatment; where
   these are a way to reach someone they need the weight of a control. */
.pz-social { display: flex; flex-wrap: wrap; gap: 12px; }
.pz-social__link { display: inline-flex; align-items: center; gap: 10px; padding: 13px 22px; }
.pz-social__link svg { width: 15px; height: 15px; display: block; flex: none; }

/* -- header -------------------------------------------------------------- */

.pz-header {
	position: fixed;
	inset: 0 0 auto 0;
	z-index: 60;
	background: transparent;
	border-bottom: 1px solid transparent;
	backdrop-filter: blur(14px);
	transition: background .35s ease, border-color .35s ease;
}
.pz-header.is-scrolled,
.pz-header.is-open { background: rgba(11, 11, 12, .96); }
.pz-header.is-scrolled { border-bottom-color: var(--pz-hairline); }
/* Inner pages start with a solid bar — only the homepage hero sits under it. */
.pz-header--solid { background: rgba(11, 11, 12, .96); border-bottom-color: var(--pz-hairline); }

.pz-header__bar {
	max-width: var(--pz-container);
	margin: 0 auto;
	padding-inline: var(--pz-gutter);
	height: 92px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 32px;
	transition: height .35s ease;
}
.pz-header.is-scrolled .pz-header__bar { height: 68px; }

.pz-brand {
	font-family: var(--pz-serif);
	font-size: 19px;
	letter-spacing: .26em;
	text-transform: uppercase;
	color: var(--pz-text);
	white-space: nowrap;
}
.pz-brand:hover { color: var(--pz-text); }

.pz-nav { display: flex; align-items: center; align-self: stretch; gap: clamp(18px, 2.2vw, 34px); }
.pz-nav ul { display: flex; align-items: center; gap: clamp(18px, 2.2vw, 34px); list-style: none; margin: 0; padding: 0; }
/* The top level fills the bar height, so a dropdown at top:100% lands exactly on
   the header's bottom edge — and keeps landing there when the bar shrinks on
   scroll. It also makes the whole column a hover target, not just the word. */
.pz-nav > ul { align-self: stretch; align-items: stretch; }
.pz-nav > ul > li { display: flex; align-items: center; }
.pz-nav a { font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: #BDB8B0; white-space: nowrap; }
.pz-nav a:hover,
.pz-nav .current-menu-item > a { color: var(--pz-text); }
.pz-nav .current-menu-parent > a,
.pz-nav .current-menu-ancestor > a { color: var(--pz-text); }

/* Dropdowns. WordPress supplies .menu-item-has-children and .sub-menu on any
   menu rendered deeper than one level; the theme asks for two in header.php. */
.pz-nav .menu-item-has-children { position: relative; }
.pz-nav .menu-item-has-children > a::after {
	content: '';
	display: inline-block;
	width: 5px;
	height: 5px;
	margin-left: 9px;
	vertical-align: 2px;
	border-right: 1px solid currentColor;
	border-bottom: 1px solid currentColor;
	transform: rotate(45deg);
}
.pz-nav .sub-menu {
	position: absolute;
	top: 100%;
	left: 50%;
	z-index: 5;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0;
	min-width: 210px;
	margin: 0;
	padding: 8px 0;
	background: rgba(11, 11, 12, .97);
	border: 1px solid var(--pz-hairline);
	box-shadow: 0 24px 48px rgba(0, 0, 0, .45);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transform: translate(-50%, -6px);
	transition: opacity .25s ease, transform .25s ease, visibility .25s;
}
.pz-nav .menu-item-has-children:hover > .sub-menu,
.pz-nav .menu-item-has-children:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: translate(-50%, 0);
}
.pz-nav .sub-menu li { width: 100%; }
.pz-nav .sub-menu a {
	display: block;
	padding: 11px 22px;
	font-size: 11px;
	letter-spacing: .16em;
}
.pz-nav .sub-menu a:hover { color: var(--pz-text); background: rgba(237, 233, 227, .05); }
.pz-nav__cta {
	font-size: 11px;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--pz-gold-light);
	border: 1px solid rgba(200, 161, 90, .55);
	padding: 11px 22px;
	white-space: nowrap;
	transition: background .25s ease, border-color .25s ease;
}
.pz-nav__cta:hover { background: rgba(200, 161, 90, .12); border-color: var(--pz-gold); }

.pz-burger {
	display: none;
	width: 48px;
	height: 48px;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 1px solid rgba(237, 233, 227, .18);
	color: var(--pz-text);
	font-size: 17px;
	cursor: pointer;
}

.pz-mobile-nav { display: none; border-top: 1px solid var(--pz-hairline); padding: 8px var(--pz-gutter) 28px; }
.pz-header.is-open .pz-mobile-nav { display: flex; flex-direction: column; }
.pz-mobile-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
/* Scoped to the list, not to every link in the panel. Unscoped, this rule also
   caught the Contact button that sits below the menu — and beat .pz-btn--primary
   on specificity, so the button lost its dark ink to #BDB8B0 on gold (1.22:1,
   about as close to invisible as two colours get), its 17px 36px padding, and
   gained a stray hairline across its bottom edge. The only link in this panel
   outside the ul is that button, so scoping here is exactly the fix. */
.pz-mobile-nav ul a {
	display: block;
	font-size: 14px;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: #BDB8B0;
	padding: 18px 0;
	border-bottom: 1px solid rgba(237, 233, 227, .07);
}
.pz-mobile-nav ul a:hover { color: var(--pz-text); }
/* Sub-items stay in the flow on mobile — indented under their parent rather
   than hidden behind a tap target, so the whole tree is one scroll. */
.pz-mobile-nav .sub-menu { padding-left: 22px; }
.pz-mobile-nav .sub-menu a {
	font-size: 12px;
	padding: 14px 0;
	color: var(--pz-muted);
}
.pz-mobile-nav .pz-btn { margin-top: 22px; }

/* Inner pages need clearance under the fixed header. */
.pz-page-top { padding-top: 92px; }

@media (max-width: 999px) {
	.pz-nav { display: none; }
	.pz-burger { display: flex; }
	.pz-header__bar { height: 72px; }
	.pz-page-top { padding-top: 72px; }
}

/* -- hero ---------------------------------------------------------------- */

.pz-hero {
	position: relative;
	/* svh rather than vh: on iOS 100vh measures the viewport with the address
	   bar hidden, so a vh-sized hero is always taller than the screen actually
	   showing it. The vh line stays as the fallback. */
	min-height: min(100vh, 940px);
	min-height: min(100svh, 940px);
	display: flex;
	align-items: flex-end;
	overflow: hidden;
}
.pz-hero__media,
.pz-hero__media img,
.pz-hero__media video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 58% 34%;
	filter: grayscale(1) contrast(1.06) brightness(.94);
}
.pz-hero__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(100deg, #0B0B0C 4%, rgba(11, 11, 12, .86) 34%, rgba(11, 11, 12, .28) 66%, rgba(11, 11, 12, .55) 100%);
}
.pz-hero__fade { position: absolute; left: 0; right: 0; bottom: 0; height: 220px; background: linear-gradient(to top, var(--pz-bg), transparent); }
.pz-hero__inner {
	position: relative;
	z-index: 2;
	width: 100%;
	max-width: var(--pz-container);
	margin: 0 auto;
	padding: 200px var(--pz-gutter) clamp(64px, 9vh, 112px);
}
.pz-hero h1 { margin-bottom: 22px; text-wrap: balance; }
.pz-hero__sub { max-width: 520px; font-size: clamp(15px, 1.2vw, 17px); line-height: 1.65; color: var(--pz-text-2); margin-bottom: 38px; }
.pz-hero__credibility { font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--pz-faint); margin: 44px 0 0; }

/* The hero stack was drawn for a desktop screen and did not fit a phone: at
   375x812 its content ran 884px, which left the second call to action cut in
   half by the fold and the credibility line entirely below it. These are the
   three gaps that cost the most. They are tied to vh so a shorter handset
   compresses further rather than pushing the buttons out of sight — the top
   padding still clears the 72px bar by a comfortable margin at its smallest. */
@media (max-width: 599px) {
	.pz-hero__inner { padding-top: clamp(104px, 16vh, 148px); }
	.pz-hero__sub { margin-bottom: clamp(22px, 3.4vh, 34px); }
	.pz-hero__credibility { margin-top: clamp(16px, 2.4vh, 28px); }
}

/* Compact hero used by inner pages. */
.pz-pagehead { position: relative; padding-block: clamp(120px, 15vw, 200px) clamp(48px, 6vw, 80px); overflow: hidden; }
.pz-pagehead__media { position: absolute; inset: 0; }
.pz-pagehead__media img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.05) brightness(.45); }
.pz-pagehead__media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, var(--pz-bg) 2%, rgba(11, 11, 12, .72)); }
.pz-pagehead__inner { position: relative; z-index: 2; }
.pz-pagehead h1 { font-size: clamp(38px, 5.4vw, 76px); margin-bottom: 22px; }

/*
 * Gallery-style head: the grid is the point, so the header takes less room and
 * the standfirst sits beside the title rather than under it.
 */
.pz-pagehead--compact { padding-block: clamp(88px, 10vw, 132px) clamp(24px, 3vw, 36px); }
.pz-pagehead--compact h1 { margin-bottom: 0; }
.pz-pagehead__split {
	display: grid;
	grid-template-columns: 1fr minmax(0, 34ch);
	gap: clamp(24px, 4vw, 64px);
	align-items: end;
}
.pz-pagehead__standfirst { color: var(--pz-muted); font-size: 15px; line-height: 1.7; padding-bottom: 10px; }
.pz-pagehead__standfirst p { margin: 0 0 8px; }
.pz-pagehead__standfirst p:last-child { margin-bottom: 0; }

@media (max-width: 899px) {
	.pz-pagehead__split { grid-template-columns: 1fr; align-items: start; }
	.pz-pagehead--compact h1 { margin-bottom: 18px; }
}

/* Pairs with pz-pagehead--compact: the head already provides the breathing room. */
.pz-section--tight { padding-block: clamp(26px, 3vw, 40px) var(--pz-section); }

/* -- authority strip ----------------------------------------------------- */

.pz-stats { border-top: 1px solid rgba(237, 233, 227, .08); border-bottom: 1px solid rgba(237, 233, 227, .08); }
.pz-stats__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.pz-stat {
	padding: clamp(32px, 4vw, 52px) clamp(16px, 2vw, 32px) clamp(32px, 4vw, 52px) clamp(20px, 2.4vw, 36px);
	border-left: 1px solid rgba(237, 233, 227, .08);
}
.pz-stat__value { font-family: var(--pz-serif); font-size: clamp(30px, 3.2vw, 46px); line-height: 1; color: var(--pz-gold-light); margin-bottom: 12px; }
.pz-stat__label { font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--pz-muted); }

/* -- tags & chips -------------------------------------------------------- */

.pz-tags { display: flex; flex-wrap: wrap; gap: 10px; }
.pz-tag {
	font-size: 11px;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: #A7A199;
	border: 1px solid rgba(237, 233, 227, .14);
	padding: 8px 14px;
}
.pz-chip {
	font-size: 11px;
	letter-spacing: .18em;
	text-transform: uppercase;
	padding: 10px 20px;
	border: 1px solid var(--pz-hairline-strong);
	background: transparent;
	color: var(--pz-text-2);
	cursor: pointer;
	transition: background .25s ease, color .25s ease, border-color .25s ease;
	/* Every chip is a <button>: a filter changes what is on the page, it does
	   not go anywhere. Buttons do not inherit the page font on their own, and
	   iOS rounds their corners, so both are stated here. */
	font-family: inherit;
	-webkit-appearance: none;
	appearance: none;
	border-radius: 0;
	display: inline-block;
	text-decoration: none;
	line-height: 1;
}
.pz-chip:hover { border-color: var(--pz-gold); color: var(--pz-text); }
.pz-chip.is-active { background: var(--pz-gold); border-color: var(--pz-gold); color: var(--pz-bg); }

/* -- course card --------------------------------------------------------- */

.pz-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--pz-grid-gap); }

/* Explicit column counts, per the handoff: auto-fit stretches a lone card to
   the full container, which is how one leftover workshop ended up the size of
   a hero image. Three across, then two, then one. */
.pz-card-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1099px) { .pz-card-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 699px) { .pz-card-grid--3 { grid-template-columns: minmax(0, 1fr); } }

.pz-course-card {
	display: flex;
	flex-direction: column;
	background: var(--pz-surface);
	border: 1px solid rgba(237, 233, 227, .08);
	transition: border-color .3s ease, transform .3s ease;
}
.pz-course-card:hover { border-color: rgba(200, 161, 90, .45); transform: translateY(-4px); }
.pz-course-card__media { position: relative; overflow: hidden; }
.pz-course-card__media img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; filter: grayscale(1) contrast(1.05); transition: filter .45s ease; }
/* Colour on hover, like every other photograph on the site. */
.pz-course-card:hover .pz-course-card__media img { filter: grayscale(0) contrast(1.02); }
.pz-course-card__media::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(11, 11, 12, .75), transparent 55%);
}
.pz-course-card__level {
	position: absolute;
	top: 14px;
	left: 14px;
	z-index: 2;
	font-size: 10px;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--pz-bg);
	background: var(--pz-gold);
	padding: 6px 11px;
}
.pz-course-card__body { padding: 26px 26px 28px; display: flex; flex-direction: column; flex: 1; }
.pz-course-card__body h3 { font-size: 26px; margin: 0 0 12px; color: var(--pz-text); }
.pz-course-card__desc { font-size: 14px; line-height: 1.65; color: var(--pz-muted); margin: 0 0 22px; flex: 1; text-wrap: pretty; }
.pz-course-card__meta {
	display: flex;
	align-items: center;
	gap: 16px;
	font-size: 11px;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--pz-faint);
	padding-bottom: 18px;
	border-bottom: 1px solid rgba(237, 233, 227, .08);
	margin-bottom: 18px;
}
.pz-course-card__meta span[aria-hidden] { color: #3A3835; }
.pz-course-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pz-price { font-family: var(--pz-serif); font-size: 24px; color: var(--pz-gold-light); }
.pz-price del { color: var(--pz-faint); font-size: .7em; margin-right: 8px; }
/* Stands in for a hidden course price, so it reads as a note, not a figure. */
.pz-price--note { font-size: 17px; }
.pz-course-card__cta { font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--pz-text); }

/* -- workshop card & row ------------------------------------------------- */

.pz-workshop-card { border: 1px solid var(--pz-hairline); background: var(--pz-surface); display: flex; flex-direction: column; }
.pz-workshop-card img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; filter: grayscale(1) contrast(1.05); transition: filter .45s ease; }
.pz-workshop-card:hover img { filter: grayscale(0) contrast(1.02); }
.pz-workshop-card__body { padding: 24px 24px 26px; flex: 1; display: flex; flex-direction: column; }
.pz-workshop-card__status { font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--pz-gold); margin-bottom: 14px; }
.pz-workshop-card__status.is-past { color: var(--pz-faint); }
.pz-workshop-card h3 { font-size: 23px; line-height: 1.18; margin: 0 0 12px; color: var(--pz-text); }
.pz-workshop-card__meta { font-size: 13px; letter-spacing: .06em; color: var(--pz-muted); margin: 0 0 20px; flex: 1; }
.pz-workshop-card__cta { font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--pz-gold-light); }

.pz-workshop-row {
	display: grid;
	grid-template-columns: 300px 1fr auto;
	gap: clamp(24px, 3vw, 44px);
	align-items: center;
	padding: clamp(24px, 3vw, 36px) 0;
	border-top: 1px solid var(--pz-hairline);
}
/* Past workshops keep all three tracks — they carry a View Workshop button, so
   the column is not empty. Only the price and spot count are dropped. */
.pz-workshop-row img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; filter: grayscale(1) contrast(1.05); transition: filter .45s ease; }
.pz-workshop-row:hover img { filter: grayscale(0) contrast(1.02); }

/* The place in a workshop meta line links to the map. Kept quiet — it sits
   inside a run of muted metadata, so it underlines rather than turning gold. */
.pz-maplink { color: inherit; border-bottom: 1px solid rgba(200, 161, 90, .4); }
.pz-maplink:hover { color: var(--pz-gold-light); border-color: var(--pz-gold); }
/* The date leads the row: gold, serif, set at title scale so it reads before
   anything else. The status label sits beside it rather than above. */
.pz-workshop-row__head {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 8px 16px;
	margin-bottom: 10px;
}
.pz-workshop-row__date {
	font-family: var(--pz-serif);
	font-size: clamp(20px, 2vw, 27px);
	line-height: 1;
	color: var(--pz-gold);
}
.pz-workshop-row__head .pz-workshop-card__status { margin-bottom: 0; }

/* The description runs to the width of its column, capped only so the line
   does not get too long to track. An upcoming row gives up space to the price
   column, so it is the narrower of the two. */
.pz-workshop-row__excerpt { margin: 0; max-width: 68ch; }
/* A past row has no price column, so the description runs the full width of
   its column — matching the section rule above it rather than stopping short. */
.pz-workshop-row--past .pz-workshop-row__excerpt { max-width: none; }

.pz-workshop-row h3 { margin: 0 0 10px; }
.pz-workshop-row__aside { text-align: right; display: flex; flex-direction: column; gap: 14px; align-items: flex-end; }
@media (max-width: 899px) {
	.pz-workshop-row,
	.pz-workshop-row--past { grid-template-columns: 1fr; }
	.pz-workshop-row__aside { text-align: left; align-items: flex-start; }
}

/* -- testimonial --------------------------------------------------------- */

.pz-testimonial { text-align: center; max-width: 1100px; margin: 0 auto; }
.pz-testimonial__mark { font-family: var(--pz-serif); font-size: 72px; line-height: 1; color: rgba(200, 161, 90, .45); display: block; margin-bottom: 8px; }
.pz-testimonial blockquote { font-family: var(--pz-serif); font-size: clamp(22px, 2.9vw, 38px); line-height: 1.38; color: var(--pz-text); margin: 0 0 34px; text-wrap: pretty; }
.pz-testimonial__name { font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--pz-gold-light); transition: color .2s ease; }

/* The person under the quote. Both parts are optional: with no avatar this is
   the name exactly where it always sat, and with no Instagram there is no link
   wrapping it — the spacing comes from the wrapper either way. */
.pz-testimonial__person,
.pz-testimonial__person > a { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.pz-testimonial__person { margin-bottom: 6px; }
.pz-testimonial__person > a { text-decoration: none; }
.pz-testimonial__avatar {
	width: 58px; height: 58px;
	border-radius: 50%;
	object-fit: cover;
	border: 1px solid var(--pz-hairline);
	filter: grayscale(1) contrast(1.05);
	transition: filter .5s ease;
}
.pz-testimonial__person > a:hover .pz-testimonial__avatar { filter: none; }
.pz-testimonial__person > a:hover .pz-testimonial__name { color: var(--pz-gold); }
.pz-testimonial__meta { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--pz-faint); }
/* The dots sit beside the play/pause control rather than alone, so the row is
   what carries the spacing now. align-items keeps the active bar centred on the
   others once it grows taller. */
.pz-rotator-controls { display: flex; align-items: center; justify-content: center; gap: clamp(14px, 2vw, 22px); margin-top: 38px; }
.pz-dots { display: flex; align-items: center; justify-content: center; gap: 10px; }
/* A 2px bar is a good mark and an impossible target — 34x2 is nothing to a
   thumb. The pseudo-element carries the 44px tap area: absolutely positioned,
   so it draws nothing and costs no layout, and the bar keeps both its two
   pixels and the 10px spacing between one dot and the next. */
/* .18 measured 1.56:1 against the ground. These are buttons, so the bar is the
   control's whole visible form and SC 1.4.11 wants 3:1 — .38 gives 3.11. */
.pz-dots button { position: relative; width: 34px; height: 2px; border: 0; padding: 0; cursor: pointer; background: var(--pz-hairline-strong); transition: background .3s ease, height .3s ease; }
.pz-dots button::before { content: ''; position: absolute; left: 0; right: 0; top: -21px; bottom: -21px; }
/*
 * The active bar is taller as well as gold. Colour alone could not carry this:
 * an idle bar needs 3:1 against the black to be visible at all, and the gold
 * needs 3:1 against the idle bar to read as a different state — and no grey
 * satisfies both at once, because the two requirements pull in opposite
 * directions. Height is the way out, and it survives a colour-blind reader and
 * a monochrome screen, which a hue change would not.
 */
.pz-dots button.is-active { background: var(--pz-gold); height: 4px; }

/*
 * Play/pause for the quote rotator. It exists because the quotes advance on
 * their own every seven seconds, and anything that moves by itself for longer
 * than five needs a way to stop it — a visitor who reads slowly, or with a
 * screen magnifier, otherwise loses the sentence mid-way with no recourse.
 * Hover already paused it; hovering is not something a keyboard or a touch
 * screen can do.
 *
 * 32px square, comfortably past the 24px minimum, and quiet enough to sit
 * beside the dots without competing with the quote above it.
 */
.pz-rotator-toggle {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	background: transparent;
	border: 1px solid var(--pz-hairline-strong);
	color: var(--pz-text-2);
	cursor: pointer;
	border-radius: 0;
	-webkit-appearance: none;
	appearance: none;
	transition: color .25s ease, border-color .25s ease;
}
.pz-rotator-toggle:hover { color: var(--pz-text); border-color: var(--pz-gold); }
.pz-rotator-toggle svg { width: 11px; height: 11px; display: block; fill: currentColor; }
/* One button, two glyphs — the script swaps the class and the label together. */
.pz-rotator-toggle .pz-rotator-toggle__play { display: none; }
.pz-rotator-toggle.is-paused .pz-rotator-toggle__play { display: block; }
.pz-rotator-toggle.is-paused .pz-rotator-toggle__pause { display: none; }

.pz-testimonial-card { border: 1px solid var(--pz-hairline); padding: clamp(24px, 3vw, 38px); background: var(--pz-surface); }
.pz-testimonial-card blockquote { font-family: var(--pz-serif); font-size: 20px; line-height: 1.45; margin: 0 0 22px; }
.pz-testimonial-card__name { font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--pz-gold-light); }
.pz-testimonial-card__meta { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--pz-faint); margin-top: 6px; }

/* Testimonials page. The card's person row mirrors the rotator's but reads as
   a line rather than a stack — there is less width to play with, and the quote
   above it is already the centre of attention. */
.pz-testimonial-card { display: flex; flex-direction: column; }
.pz-testimonial-card blockquote { flex: 1; }
.pz-testimonial-card__person,
.pz-testimonial-card__person > a { display: flex; align-items: center; gap: 14px; text-decoration: none; }
.pz-testimonial-card__person .pz-testimonial__avatar { width: 46px; height: 46px; }
.pz-testimonial-card__person > a:hover .pz-testimonial__avatar { filter: none; }
.pz-testimonial-card__person > a:hover .pz-testimonial-card__name { color: var(--pz-gold); }
.pz-testimonial-card__name,
.pz-testimonial-card__meta { display: block; transition: color .2s ease; }

/* Consent checkbox. Not a .pz-field: that label is a small-caps field name and
   this one is a sentence the visitor has to actually read. */
.pz-check { display: flex; align-items: flex-start; gap: 12px; margin: 0; }
.pz-check input { flex: none; margin-top: 3px; width: 16px; height: 16px; accent-color: var(--pz-gold); }
.pz-check label { font-size: 14px; line-height: 1.5; color: var(--pz-text-2); }


/* -- pillars & timeline -------------------------------------------------- */

.pz-pillar { padding: clamp(28px, 3vw, 42px) clamp(20px, 2vw, 30px); }
.pz-pillar__num { font-family: var(--pz-serif); font-size: 15px; color: var(--pz-gold); margin-bottom: 22px; }
.pz-pillar h3 { font-family: var(--pz-sans); font-size: 13px; font-weight: 500; letter-spacing: .2em; text-transform: uppercase; color: var(--pz-text); margin: 0 0 14px; }
.pz-pillar p { font-size: 14px; line-height: 1.65; color: var(--pz-muted); margin: 0; text-wrap: pretty; }

.pz-timeline { display: flex; flex-direction: column; }
.pz-timeline__item {
	display: grid;
	grid-template-columns: 96px 1fr;
	gap: 24px;
	padding: 26px 0;
	border-top: 1px solid var(--pz-hairline);
	align-items: baseline;
}
.pz-timeline__item:last-child { border-bottom: 1px solid var(--pz-hairline); }
.pz-timeline__year { font-family: var(--pz-serif); font-size: 22px; color: var(--pz-gold); }
.pz-timeline__item h3 { font-family: var(--pz-sans); font-size: 17px; font-weight: 500; color: var(--pz-text); margin: 0 0 8px; }
.pz-timeline__item p { font-size: 14px; line-height: 1.6; color: var(--pz-muted); margin: 0; }
@media (max-width: 599px) { .pz-timeline__item { grid-template-columns: 1fr; gap: 8px; } }

/* -- list rows (private lessons, included, outcomes) --------------------- */

.pz-rows { display: flex; flex-direction: column; gap: 1px; background: var(--pz-hairline); }
.pz-rows > div { background: var(--pz-bg); padding: 20px 0 20px 22px; display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; }
.pz-section--alt .pz-rows > div { background: var(--pz-bg-alt); }
.pz-rows__key { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--pz-gold-light); min-width: 170px; }
.pz-rows__val { font-size: 14px; color: var(--pz-muted); }

/* Label above value rather than beside it.
   The default row is a two-column definition — a short key, a short value, side
   by side. It only holds while both stay short: the key reserves 170px, so once
   the value needs more room than the rest of the row has, it wraps to the next
   line and the pair reads as two loose fragments rather than one entry. That is
   guaranteed in a narrow column, such as the one beside a portrait image.
   Stacking is the honest layout for a label and a sentence. */
.pz-rows--stack > div { flex-direction: column; align-items: flex-start; gap: 6px; }
.pz-rows--stack .pz-rows__key { min-width: 0; }
.pz-rows--stack .pz-rows__val { font-size: 15px; color: var(--pz-text-2); }

.pz-checklist { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1px 0; }
.pz-checklist li {
	display: flex;
	gap: 14px;
	align-items: baseline;
	padding: 16px 24px 16px 0;
	border-top: 1px solid var(--pz-hairline);
	font-size: 15px;
	color: var(--pz-text-2);
}
.pz-checklist li::before { content: '—'; color: var(--pz-gold); flex: none; }

/* -- accordion ----------------------------------------------------------- */

.pz-accordion { border-top: 1px solid var(--pz-hairline); }
.pz-accordion__item { border-bottom: 1px solid var(--pz-hairline); }
.pz-accordion__trigger {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	background: transparent;
	border: 0;
	color: var(--pz-text);
	font-family: var(--pz-serif);
	font-size: clamp(17px, 1.6vw, 21px);
	text-align: left;
	padding: clamp(24px, 2.4vw, 28px) 0;
	cursor: pointer;
}
.pz-accordion__marker { color: var(--pz-gold); font-size: 20px; flex: none; line-height: 1; }
.pz-accordion__panel { display: none; padding: 0 clamp(24px, 6vw, 96px) 28px 0; color: var(--pz-text-2); font-size: 15px; line-height: 1.75; }
.pz-accordion__item.is-open .pz-accordion__panel { display: block; }

/* -- purchase block ------------------------------------------------------ */

.pz-purchase { border: 1px solid rgba(200, 161, 90, .5); padding: clamp(26px, 3vw, 38px); background: var(--pz-surface); }
.pz-purchase__price { font-family: var(--pz-serif); font-size: clamp(34px, 3.4vw, 48px); color: var(--pz-gold-light); line-height: 1; margin-bottom: 20px; }
.pz-purchase__price--note { font-size: clamp(24px, 2.2vw, 30px); line-height: 1.15; color: var(--pz-text); margin-bottom: 8px; }
.pz-purchase dl { display: grid; grid-template-columns: auto 1fr; gap: 10px 18px; margin: 24px 0; font-size: 13px; }
.pz-purchase dt { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--pz-faint); }
.pz-purchase dd { margin: 0; color: var(--pz-text-2); text-align: right; }
@media (min-width: 1000px) { .pz-purchase--sticky { position: sticky; top: 110px; } }

/* -- forms --------------------------------------------------------------- */

.pz-form { display: grid; gap: 28px; }
.pz-field label,
.pz-field > span {
	display: block;
	font-size: 11px;
	letter-spacing: .22em;
	text-transform: uppercase;
	color: var(--pz-faint);
	margin-bottom: 10px;
}
.pz-field input,
.pz-field select,
.pz-field textarea {
	width: 100%;
	background: transparent;
	border: 0;
	border-bottom: 1px solid var(--pz-hairline-strong);
	color: var(--pz-text);
	font-family: var(--pz-sans);
	font-size: 15px;
	font-weight: 300;
	padding: 12px 0;
	border-radius: 0;
}
.pz-field select option { background: var(--pz-surface); color: var(--pz-text); }
.pz-field textarea { min-height: 140px; resize: vertical; }
.pz-field input:focus,
.pz-field select:focus,
.pz-field textarea:focus { outline: none; border-bottom-color: var(--pz-gold); }
.pz-form__note { font-size: 13px; color: var(--pz-faint); }
.pz-notice { border-left: 2px solid var(--pz-gold); padding: 16px 20px; background: var(--pz-surface); font-size: 15px; }
.pz-notice--error { border-color: #C0574F; }

/* -- gallery ------------------------------------------------------------- */

.pz-gallery { display: grid; gap: 2px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* A lone photograph reads as a thumbnail, not a hero: roughly the width of one
   masonry tile, so a gallery of one and a gallery of six look related. Its own
   proportions are kept — no crop. */
.pz-gallery--single { display: block; }
/* Exactly one masonry column wide, gaps included, so a single photograph is the
   same size as it would be sitting in a grid of six. */
.pz-gallery--single .pz-gallery__item {
	display: block;
	max-width: calc((100% - (var(--pz-cols) - 1) * 2px) / var(--pz-cols));
}
.pz-gallery--single .pz-gallery__item img { width: 100%; height: auto; }

/* oEmbed hands back a fixed-size iframe. This holds it to 16:9 and lets it
   fill whatever column it lands in. */
.pz-embed { position: relative; margin: 0; aspect-ratio: 16 / 9; background: #000; }
.pz-embed iframe,
.pz-embed video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.pz-embed video { object-fit: contain; }

/* Video carries the same treatment as every photograph: grayscale at rest,
   colour on hover. Once it is actually playing the filter is dropped for good —
   watching a performance through a grey veil, and having it turn grey again the
   moment the pointer leaves, would be worse than not doing this at all. */
.pz-embed iframe,
.pz-embed video { filter: grayscale(1) contrast(1.05); transition: filter .45s ease; }
@media (hover: hover) {
	.pz-embed:hover iframe,
	.pz-embed:hover video { filter: grayscale(0) contrast(1); }
}
.pz-embed.is-playing iframe,
.pz-embed.is-playing video { filter: none; }

/* Six columns rather than three, so each image renders at half the width — and
   therefore half the height, since masonry keeps the original proportions.
   Phone screenshots are close to 9:20, and at three across a handful of them
   ran longer than the rest of the page. They are thumbnails into the lightbox,
   not the presentation itself.

   The column count is a variable because a lone photograph has to match it: it
   is sized to exactly one column, so a gallery of one and a gallery of six show
   images at the same size. Set it once, both follow. */
.pz-gallery--masonry,
.pz-gallery--single { --pz-cols: 6; }
@media (max-width: 1399px) { .pz-gallery--masonry, .pz-gallery--single { --pz-cols: 5; } }
@media (max-width: 1099px) { .pz-gallery--masonry, .pz-gallery--single { --pz-cols: 4; } }
@media (max-width: 899px) { .pz-gallery--masonry, .pz-gallery--single { --pz-cols: 3; } }

.pz-gallery--masonry { display: block; column-count: var(--pz-cols); column-gap: 2px; }
.pz-gallery--masonry .pz-gallery__item { break-inside: avoid; margin-bottom: 2px; }
.pz-gallery__item { display: block; overflow: hidden; }
.pz-gallery__item img {
	width: 100%;
	object-fit: cover;
	filter: grayscale(1) contrast(1.05) brightness(.92);
	transition: transform .6s cubic-bezier(.22, .61, .36, 1), filter .4s ease;
}
/* Grid galleries crop to a common ratio so rows line up. Masonry keeps each
   photograph's own shape, and so does a lone image. */
.pz-gallery:not(.pz-gallery--masonry):not(.pz-gallery--single) .pz-gallery__item img { aspect-ratio: 3 / 4; }

/* Hover (or keyboard focus) restores the original colour of the photograph.
   Guarded so touch devices don't get stuck in the "hovered" state. */
@media (hover: hover) {
	.pz-gallery__item:hover img { transform: scale(1.05); filter: grayscale(0) contrast(1) brightness(1); }
}
.pz-gallery__item:focus-visible img { transform: scale(1.05); filter: grayscale(0) contrast(1) brightness(1); }

/*
 * The portfolio grid. Fixed columns rather than CSS masonry: the design lays
 * the photographs out in even rows, and a column layout also reshuffles every
 * tile each time "load more" appends to it.
 */
.pz-gallery--portfolio {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 8px;
	column-count: initial;
}
.pz-gallery--portfolio .pz-gallery__item { margin-bottom: 0; }
/* Outweighs .pz-gallery:not(.pz-gallery--masonry) … img, which is otherwise
   more specific and would impose its 3:4. */
.pz-gallery.pz-gallery--portfolio .pz-gallery__item img { aspect-ratio: 4 / 5; height: 100%; }

@media (max-width: 1199px) { .pz-gallery--portfolio { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 799px) { .pz-gallery--portfolio { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/*
 * Captions no longer print in the grid — they belong to the lightbox, where
 * there is one photograph to talk about instead of a wall of them. The
 * positioning context stays: overlays are still anchored to the item.
 */
.pz-gallery__item { position: relative; }

/* Filter chips on the left, the count on the right, hairline beneath. */
.pz-gallery-bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	flex-wrap: wrap;
	padding-bottom: 20px;
	margin-bottom: clamp(20px, 2.4vw, 30px);
	border-bottom: 1px solid var(--pz-hairline);
}
.pz-gallery-bar__count {
	margin: 0;
	white-space: nowrap;
	font-size: 11px;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--pz-text-2);
}

.pz-gallery__more { display: flex; justify-content: center; margin-top: clamp(28px, 4vw, 44px); }
.pz-gallery__more [hidden] { display: none; }
.pz-gallery__more .is-loading { opacity: .55; pointer-events: none; }
/*
 * Announced to screen readers, invisible otherwise — the count in the bar
 * already says the same thing on screen. Errors are the exception and get
 * shown, since the visitor has to know the button did nothing.
 */
.pz-gallery__status {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}
.pz-gallery__status.is-error {
	position: static;
	width: auto;
	height: auto;
	overflow: visible;
	clip-path: none;
	white-space: normal;
	margin-top: 24px;
	text-align: center;
	font-size: 12px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--pz-gold-light);
}
.pz-gallery[aria-busy="true"] { opacity: .6; transition: opacity .2s ease; }

.pz-feed { display: grid; gap: 2px; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.pz-feed .pz-gallery__item img { aspect-ratio: 1 / 1; }

@media (max-width: 1099px) { .pz-feed { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 699px) {
	.pz-gallery, .pz-feed { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	/* Sets the shared variable rather than column-count, so a lone photograph
	   narrows to match instead of staying at the wider three-column size. */
	.pz-gallery--masonry, .pz-gallery--single { --pz-cols: 2; }
}

/* -- photo map ----------------------------------------------------------- */

.pz-mapsection { border-top: 1px solid var(--pz-hairline); }
/*
 * The isolation is load-bearing. Leaflet stacks its own furniture high — panes
 * at z-index 400, the control corners at 1000 — and gives the container nothing
 * but `position: relative`, so none of it was contained: every one of those
 * numbers landed in the root stacking context, where they beat the lightbox at
 * 200. Opening a photograph on the gallery page drew the map over it. Isolating
 * the map gives Leaflet a stacking context to spend those numbers inside, where
 * they order the map against itself and nothing else.
 */
.pz-map {
	position: relative;
	isolation: isolate;
	height: clamp(360px, 46vw, 560px);
	background: var(--pz-bg-alt);
	border: 1px solid var(--pz-hairline);
}

/*
 * OpenStreetMap tiles are bright and colourful. The same treatment the
 * photographs get — inverted so land stays light-on-dark — turns them into a
 * monochrome map that belongs on this site. Same trick, no second tile
 * provider, and the attribution stays intact.
 */
.pz-map .leaflet-tile-pane { filter: grayscale(1) invert(1) brightness(.92) contrast(.9); }

/* Gold pins. The tile filter above is scoped to the tile pane, so it never
   touches these — the markers keep their real colour over a monochrome map. */
.pz-map__pin svg { width: 26px; height: 34px; display: block; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .55)); }
.pz-map__pin svg path { fill: var(--pz-gold); }
.pz-map__pin svg circle { fill: var(--pz-bg); }
.pz-map__pin:hover svg path { fill: var(--pz-gold-light); }

.pz-map .leaflet-container { background: var(--pz-bg-alt); font-family: var(--pz-sans); }
.pz-map .leaflet-bar a,
.pz-map .leaflet-control-attribution {
	background: rgba(11, 11, 12, .86);
	color: var(--pz-text-2);
	border-color: var(--pz-hairline-strong);
}
.pz-map .leaflet-bar a:hover { background: rgba(11, 11, 12, .96); color: var(--pz-text); }
.pz-map .leaflet-control-attribution a { color: var(--pz-gold-light); }

.pz-map .leaflet-popup-content-wrapper,
.pz-map .leaflet-popup-tip {
	background: var(--pz-bg);
	color: var(--pz-text);
	border: 1px solid var(--pz-hairline-strong);
	border-radius: 0;
	box-shadow: 0 12px 40px rgba(0, 0, 0, .5);
}
.pz-map .leaflet-popup-content { margin: 14px 16px; width: 232px !important; }
.pz-map .leaflet-popup-close-button { color: var(--pz-text-2) !important; }

.pz-map__place { margin: 0 0 2px; font-size: 14px; color: var(--pz-text); }
.pz-map__count {
	margin: 0 0 10px;
	font-size: 10px;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--pz-gold-light);
}
/* Workshop pins list what was taught there instead of showing thumbnails. */
.pz-map__workshops { display: flex; flex-direction: column; }
.pz-map__workshop {
	display: block;
	padding: 8px 0;
	border-top: 1px solid var(--pz-hairline);
	color: var(--pz-text);
}
.pz-map__workshop:hover { color: var(--pz-gold-light); }
.pz-map__workshop-title { display: block; font-family: var(--pz-serif); font-size: 14px; line-height: 1.25; }
.pz-map__workshop-meta {
	display: block;
	margin-top: 3px;
	font-size: 10px;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--pz-faint);
}

.pz-map__thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; }
.pz-map__thumbs img {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	filter: grayscale(1) contrast(1.05);
	transition: filter .3s ease;
}
.pz-map__thumbs a:hover img { filter: grayscale(0); }

/* -- "more on instagram" ------------------------------------------------- */

.pz-igcta { border-top: 1px solid var(--pz-hairline); padding-block: clamp(56px, 7vw, 92px); }
.pz-igcta__inner { text-align: center; }
.pz-igcta__title { margin: 0 0 16px; font-size: clamp(28px, 3.6vw, 46px); }
.pz-igcta__body {
	margin: 0 auto 30px;
	max-width: 46ch;
	color: var(--pz-muted);
	font-size: 15px;
	line-height: 1.7;
}
/* The tiles sit between the standfirst and the button, so the button stays the
   last thing read — it is the action the block exists for. */
.pz-igcta__feed { margin-bottom: clamp(28px, 3.4vw, 40px); text-align: left; }
.pz-igcta__btn { display: inline-flex; align-items: center; gap: 10px; }
.pz-igcta__icon { flex: none; }

/* -- lightbox ------------------------------------------------------------ */

.pz-lightbox {
	position: fixed;
	inset: 0;
	z-index: 200;
	display: none;
	align-items: center;
	justify-content: center;
	background: rgba(11, 11, 12, .96);
	padding: clamp(20px, 5vw, 64px);
}
.pz-lightbox.is-open { display: flex; }
.pz-lightbox img { max-width: 100%; max-height: 88vh; object-fit: contain; }
/*
 * The caption bar. Was marked screen-reader-text, so it was announced but never
 * drawn. Collapses when the photograph has no caption rather than leaving an
 * empty strip under it.
 */
.pz-lightbox__caption {
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	bottom: clamp(16px, 3vw, 32px);
	max-width: min(70ch, 86vw);
	margin: 0;
	text-align: center;
	font-size: 13px;
	line-height: 1.5;
	color: var(--pz-text-2);
}
.pz-lightbox__caption:empty { display: none; }
.pz-lightbox__close,
.pz-lightbox__nav {
	position: absolute;
	background: transparent;
	border: 1px solid var(--pz-hairline-strong);
	color: var(--pz-text);
	width: 48px;
	height: 48px;
	cursor: pointer;
	font-size: 18px;
}
.pz-lightbox__close { top: 24px; right: 24px; }
.pz-lightbox__nav--prev { left: 24px; top: 50%; transform: translateY(-50%); }
.pz-lightbox__nav--next { right: 24px; top: 50%; transform: translateY(-50%); }

/* -- feature band (full-bleed image + copy) ------------------------------ */

.pz-band { position: relative; min-height: min(88vh, 820px); display: flex; align-items: center; overflow: hidden; }
.pz-band > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 40% 30%; filter: grayscale(1) contrast(1.08) brightness(.9); }
.pz-band__scrim { position: absolute; inset: 0; background: linear-gradient(260deg, #0B0B0C 6%, rgba(11, 11, 12, .82) 36%, rgba(11, 11, 12, .25) 72%); }
.pz-band__inner { position: relative; z-index: 2; width: 100%; max-width: var(--pz-container); margin: 0 auto; padding: clamp(64px, 8vw, 110px) var(--pz-gutter); display: flex; justify-content: flex-end; }
.pz-band__inner > div { max-width: 520px; }
.pz-band p { color: #C3BDB5; }

/* -- final CTA ----------------------------------------------------------- */

.pz-cta { position: relative; overflow: hidden; }
.pz-cta > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 22%; filter: grayscale(1) contrast(1.05) brightness(.5); }
.pz-cta__scrim { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 55%, rgba(11, 11, 12, .72) 0%, rgba(11, 11, 12, .94) 62%); }
.pz-cta__inner { position: relative; z-index: 2; max-width: 840px; margin: 0 auto; padding: clamp(90px, 13vw, 190px) var(--pz-gutter); text-align: center; }
.pz-cta__inner h2 { font-size: clamp(34px, 5.6vw, 76px); line-height: 1.02; margin-bottom: 26px; text-wrap: balance; }
.pz-cta__inner p { color: var(--pz-text-2); max-width: 50ch; margin: 0 auto 42px; }
.pz-cta__eyebrow { font-size: 11px; letter-spacing: .3em; text-transform: uppercase; color: var(--pz-gold); margin-bottom: 28px; }

/* -- footer -------------------------------------------------------------- */

.pz-footer { border-top: 1px solid var(--pz-hairline); background: var(--pz-bg); }
.pz-footer__grid {
	max-width: var(--pz-container);
	margin: 0 auto;
	padding: clamp(48px, 6vw, 80px) var(--pz-gutter) 32px;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: clamp(32px, 4vw, 56px);
}
.pz-footer__brand { font-family: var(--pz-serif); font-size: 19px; letter-spacing: .26em; text-transform: uppercase; color: var(--pz-text); margin-bottom: 18px; }
.pz-footer p { font-size: 14px; line-height: 1.7; color: var(--pz-faint); max-width: 32ch; }
.pz-footer__heading { font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--pz-gold); margin-bottom: 20px; }
.pz-footer__links,
.pz-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.pz-footer__links a,
.pz-footer ul a { font-size: 14px; color: #A7A199; font-weight: 300; }
.pz-footer__links a:hover,
.pz-footer ul a:hover { color: var(--pz-text); }
/* The row sat tight under the tagline and read as part of it. The extra
   space is what separates the two, now that these are marks rather than a
   continuation of the sentence above. */
/* The padding is the tap target and the negative margin takes it straight back
   out of the layout, so the icons are 33px to a thumb while occupying exactly
   the 19px box they draw. The words these replaced were wide enough to hit; a
   glyph on its own is not. Flex gap measures between margin boxes, which the
   negative margins pull back flush with the icon — so gap here is the spacing
   you actually see between one icon and the next.

   Size and gap are held down because this column is only ~250px at 1280 and
   ~290px above that: at 19px with a 20px gap, eight icons needed 292px and
   fell onto a second line. A fixed gap rather than a viewport-scaled one,
   because the column is widest exactly where the viewport is narrowest — on
   mobile the whole footer is one column, and a vw-scaled gap collapsed to its
   minimum there with 128px going spare. Wrap stays on as the safety valve for
   a longer list than this column can hold. */
.pz-footer__social { display: flex; flex-wrap: wrap; gap: 14px; margin-top: clamp(30px, 3.4vw, 42px); }
.pz-footer__social a { display: inline-flex; padding: 5px; margin: -5px; color: #A7A199; transition: color .2s ease; }
.pz-footer__social a:hover { color: var(--pz-gold-light); }
.pz-footer__social svg { width: 18px; height: 18px; display: block; }
/* The rule under this field is the only thing that draws it, so it takes the
   control token rather than its own fainter value — .2 measured 1.67:1. */
.pz-newsletter { display: flex; border-bottom: 1px solid var(--pz-hairline-strong); }
.pz-newsletter input { flex: 1; min-width: 0; background: transparent; border: 0; color: var(--pz-text); font-family: var(--pz-sans); font-size: 14px; padding: 10px 0; }
/* The outline is dropped because a rectangle around a borderless field sitting
   inside a ruled row looks like a mistake — but dropping it without a
   replacement fails WCAG 2.4.7, and this field is in the footer of every page.
   The row's own rule turns gold instead, which is the same indicator the
   contact form's fields already use. */
.pz-newsletter input:focus { outline: none; }
.pz-newsletter:focus-within { border-bottom-color: var(--pz-gold); }
.pz-newsletter button { background: transparent; border: 0; color: var(--pz-gold-light); font-size: 11px; letter-spacing: .2em; text-transform: uppercase; cursor: pointer; padding: 10px 0 10px 14px; }
.pz-newsletter button[disabled] { opacity: .55; cursor: default; }
/* Only ever shown with text in it — the JS unhides it. Gold for the reply that
   means "go and confirm", muted rose for the one that means "try again": both
   readable on the footer's black without shouting. */
.pz-newsletter__status { font-size: 12px; line-height: 1.5; margin-top: 10px; color: var(--pz-gold-light); }
.pz-newsletter__status.is-error { color: #D8A0A0; }

/* iOS Safari zooms the whole page in when you focus a field set below 16px,
   and it does not zoom back out afterwards. 15px on the contact and search
   fields and 14px in the newsletter were both under the line. Phone widths
   only — the desktop sizes are the design and stay as drawn.

   This block sits after every rule it overrides: the newsletter input is
   declared further up the file at equal specificity, so source order is what
   decides it. Moving it earlier would silently do nothing. */
@media (max-width: 599px) {
	.pz-field input,
	.pz-field select,
	.pz-field textarea,
	.pz-newsletter input { font-size: 16px; }
}

.pz-footer__legal {
	max-width: var(--pz-container);
	margin: 0 auto;
	padding: 24px var(--pz-gutter) 40px;
	border-top: 1px solid rgba(237, 233, 227, .07);
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	justify-content: space-between;
	font-size: 11px;
	letter-spacing: .14em;
	color: var(--pz-fainter);
}
.pz-footer__legal a { color: var(--pz-fainter); }

.pz-footer__credit a {
	color: var(--pz-fainter);
	border-bottom: 1px solid rgba(237, 233, 227, .18);
	transition: color .25s ease, border-color .25s ease;
}
.pz-footer__credit a:hover,
.pz-footer__credit a:focus {
	color: var(--pz-gold);
	border-bottom-color: var(--pz-gold);
}

/* -- editor content (page.php, single) ----------------------------------- */

/* A body of copy with a label beside it, rather than a lone column stranded on
   the left of a full-width section. The label takes a fixed track so the text
   gets the rest — wider than the bare editorial measure, but still capped so
   the line does not run the whole 1440px container. */
.pz-two-col--body {
	display: grid;
	grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
	gap: clamp(28px, 5vw, 80px);
	align-items: start;
}
.pz-two-col--body .pz-eyebrow { margin-bottom: 0; padding-top: 6px; }
.pz-two-col--body .pz-prose { max-width: 82ch; }
@media (max-width: 999px) {
	.pz-two-col--body { grid-template-columns: 1fr; }
	.pz-two-col--body .pz-eyebrow { margin-bottom: 20px; }
}

.pz-prose { max-width: 62ch; }
.pz-prose h2 { font-size: clamp(26px, 3vw, 40px); margin-top: 1.6em; }
.pz-prose h3 { margin-top: 1.6em; }
.pz-prose ul, .pz-prose ol { padding-left: 1.2em; color: var(--pz-text-2); }
.pz-prose li { margin-bottom: .5em; }
.pz-prose blockquote {
	border-left: 1px solid var(--pz-gold);
	margin: 2em 0;
	padding-left: 28px;
	font-family: var(--pz-serif);
	font-style: italic;
	font-size: clamp(20px, 2.2vw, 28px);
	line-height: 1.4;
}
.pz-prose img { margin: 2em 0; filter: grayscale(1) contrast(1.05); transition: filter .45s ease; }
.pz-prose a { border-bottom: 1px solid rgba(200, 161, 90, .45); }

/* Preformatted blocks keep their monospace face but wrap, so a long line
   cannot push the column wider than the page. */
.pz-prose pre { white-space: pre-wrap; word-break: break-word; margin: 1.5em 0; }

/* An image inside editor content behaves like one in the gallery: colour on
   hover, and a click opens it full size. The wrapping link is added in PHP, so
   it must not pick up the gold underline every other prose link gets. */
.pz-prose .pz-prose__image { display: block; border-bottom: 0; cursor: zoom-in; }
.pz-prose .pz-prose__image img { margin: 0; }
.pz-prose figure > .pz-prose__image img,
.pz-prose .pz-prose__image + figcaption { margin-top: 0; }
@media (hover: hover) {
	.pz-prose .pz-prose__image:hover img { filter: grayscale(0) contrast(1); }
}
.pz-prose .pz-prose__image:focus-visible img { filter: grayscale(0) contrast(1); }

/* -- breadcrumbs & pagination -------------------------------------------- */

.pz-crumbs { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--pz-faint); margin-bottom: 24px; }
.pz-crumbs a { color: var(--pz-faint); }
.pz-crumbs a:hover { color: var(--pz-gold-light); }

.pz-pagination { display: flex; gap: 8px; justify-content: center; margin-top: clamp(40px, 5vw, 68px); }
.pz-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	height: 44px;
	padding: 0 12px;
	border: 1px solid var(--pz-hairline);
	color: var(--pz-text-2);
	font-size: 13px;
}
.pz-pagination .page-numbers.current,
.pz-pagination .page-numbers:hover { border-color: var(--pz-gold); color: var(--pz-gold-light); }

/* -- motion -------------------------------------------------------------- */

@keyframes pz-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
.pz-rise { animation: pz-rise .9s cubic-bezier(.22, .61, .36, 1) both; }

.pz-reveal { opacity: 0; transform: translateY(18px); transition: opacity .8s cubic-bezier(.22, .61, .36, 1), transform .8s cubic-bezier(.22, .61, .36, 1); }
.pz-reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
	.pz-reveal { opacity: 1; transform: none; }
}

/* -- accessibility ------------------------------------------------------- */

.screen-reader-text {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
.pz-skip-link {
	position: absolute;
	left: -9999px;
	z-index: 999;
	background: var(--pz-gold);
	color: var(--pz-bg);
	padding: 12px 20px;
	font-size: 12px;
	letter-spacing: .2em;
	text-transform: uppercase;
}
.pz-skip-link:focus { left: 16px; top: 16px; color: var(--pz-bg); }

/* The skip link's landing place. #main carries tabindex="-1" so Safari moves
   focus there rather than only scrolling, which means it can match
   :focus-visible and draw the gold ring — around the entire page. It is not in
   the tab order and is not a control, so there is no focus to indicate. */
#main:focus,
#main:focus-visible { outline: none; }
