/*
 * Plinthworks — supplemental front-end styles.
 *
 * Only styles that cannot be expressed in theme.json belong here:
 * pseudo-element content, backdrop-filter, complex CSS animations,
 * and ::marker overrides.
 *
 * Default to theme.json; use this file as the last resort.
 */

/* Scroll reveal is defined once, further down ("Scroll reveal — auto-applied
   by reveal.js"). .js-reveal is handled there too. */

/* ==========================================================================
   Block style: Check list (::marker)
   is-style-plinthworks-check-list — coloured checkmark markers.
   ========================================================================== */

.is-style-plinthworks-check-list,
.is-style-plinthworks-checkmarks {
	list-style: none;
	padding-left: 0;
}

.is-style-plinthworks-check-list li,
.is-style-plinthworks-checkmarks li {
	position: relative;
	padding-left: 1.75em;
}

.is-style-plinthworks-check-list li::before,
.is-style-plinthworks-checkmarks li::before {
	content: '';
	position: absolute;
	left: 0;
	top: 0.35em;
	width: 1em;
	height: 1em;
	background-color: var(--wp--preset--color--accent, currentColor);
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

/* ==========================================================================
   Block style: Icon list
   is-style-plinthworks-icon-list — an accent arrow marker.

   Phase 4 audit: this variation was registered and carried only
   "list-style: none; padding-left: 0" in theme.json, which made it byte-for-byte
   the same thing as is-style-plinthworks-no-bullets. It drew no icon at all.
   The marker below uses the same mask mechanism as the check list, so both
   markers take their colour from one token and neither ships an image file.
   ========================================================================== */

.is-style-plinthworks-icon-list {
	list-style: none;
	padding-left: 0;
}

.is-style-plinthworks-icon-list li {
	position: relative;
	padding-left: 1.75em;
}

.is-style-plinthworks-icon-list li::before {
	content: '';
	position: absolute;
	left: 0;
	top: 0.35em;
	width: 1em;
	height: 1em;
	background-color: var(--wp--preset--color--accent, currentColor);
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='9 18 15 12 9 6'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='9 18 15 12 9 6'/%3E%3C/svg%3E");
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

/* ==========================================================================
   Block style: No-style list
   is-style-plinthworks-no-style — strips list decoration, useful for nav
   lists in footers and sidebars.
   ========================================================================== */

.is-style-plinthworks-no-bullets {
	list-style: none;
	padding-left: 0;
}

.is-style-plinthworks-no-bullets li + li {
	margin-top: var(--wp--preset--spacing--30, 0.5rem);
}

/* ==========================================================================
   Block style: Outline button
   is-style-plinthworks-outline — transparent fill, coloured border.
   ========================================================================== */

.wp-block-button.is-style-plinthworks-outline .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--surface-deep, currentColor);
	border: 1.5px solid var(--wp--preset--color--surface-deep, currentColor);
	box-shadow: none;
}

/* Sharper hover: fill with the accent and match the border to it. The fill and
   text colour were previously declared here and again in a second copy of this
   selector ~1450 lines further down, which won; the two are now one rule. */
.wp-block-button.is-style-plinthworks-outline .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--on-action);
	border-color: var(--wp--preset--color--accent);
	filter: none;
}

/* ==========================================================================
   Button icons (plinthworks/button-icon)
   A Lucide icon inside a core button. The icon element is injected by the
   render filter on the front end and by the editor script on the canvas; here
   it is only sized and spaced. The icon svg comes from the lucide runtime.
   ========================================================================== */

.wp-block-button__link .pw-btn-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	vertical-align: middle;
	line-height: 0;
}
/* Sizing and spacing live in one place further down (search pw-btn-icon), so
   that the padding compensation cannot drift from the icon's real footprint.
   The 1.1em rule that used to be here fought with it and is gone. */

/* Icon-only: hide the label, keep the icon centred. Works via the "Icon only"
   position, the registered "Icon only" block style, or both. */
.wp-block-button__link.pw-btn-icon-only,
.wp-block-button.is-style-plinthworks-icon .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0;
	aspect-ratio: 1;
	padding-inline: 0.7em;
	font-size: 0;              /* hide the text label, keep the icon */
}
.wp-block-button__link.pw-btn-icon-only .pw-btn-icon,
.wp-block-button.is-style-plinthworks-icon .wp-block-button__link .pw-btn-icon {
	font-size: 1rem;
	margin: 0;
}
.wp-block-button__link .pw-btn-icon--only { margin: 0; }

/* ==========================================================================
   Block style: Ghost button
   is-style-plinthworks-ghost — no background, no border, text-only.
   ========================================================================== */

.wp-block-button.is-style-plinthworks-ghost .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--surface-deep, currentColor);
	border: 1.5px solid transparent;
	box-shadow: none;
}

.wp-block-button.is-style-plinthworks-ghost .wp-block-button__link:hover {
	background-color: color-mix(in srgb, var(--wp--preset--color--accent, #EFC940) 12%, transparent);
	color: var(--wp--preset--color--surface-deep, currentColor);
	filter: none;
}

/* ==========================================================================
   Block style: Card (group)
   is-style-plinthworks-card — subtle border, background, and radius.
   ========================================================================== */

.wp-block-group.is-style-plinthworks-card {
	border: 1px solid var(--wp--preset--color--base-3, #C8C8C8);
	border-radius: var(--wp--custom--radius--medium, 8px);
	background-color: var(--wp--preset--color--base, #fff);
	/* Refined base shadow. Previously declared here as the `natural` preset and
	   then silently replaced by a second copy of this selector further down the
	   file; the preset value never reached the page. Folded into one rule. */
	box-shadow:
		0 1px 3px rgba(0, 0, 0, 0.06),
		0 0 0 1px rgba(0, 0, 0, 0.04);
}

/* ==========================================================================
   Block style: Polaroid (image)
   is-style-plinthworks-polaroid — white frame with drop shadow and slight tilt.
   ========================================================================== */

/* Phase 4 audit: theme.json declared "shadow": shadow.natural on this
   variation and it never reached the page — core emits no box-shadow rule for a
   core/image variation, so that key was dead and the only live shadow was the
   two hard-coded rgba() stops below, which belong to no brand on this site. The
   token is applied here instead, and the dead key is gone from theme.json. The
   white frame takes the palette's surface colour for the same reason. */
.wp-block-image.is-style-plinthworks-polaroid img {
	padding: 0.75rem 0.75rem 2.5rem;
	background: var(--wp--preset--color--base, #fff);
	box-shadow: var(--wp--preset--shadow--natural);
	transform: rotate(-1.5deg);
}

/* ==========================================================================
   Block style: Rounded (image)
   is-style-plinthworks-rounded — large border-radius.
   ========================================================================== */

.wp-block-image.is-style-plinthworks-rounded img {
	border-radius: var(--wp--custom--radius--large, 16px);
}

/* ==========================================================================
   Block style: Pill (button)
   is-style-plinthworks-pill — fully rounded button.
   ========================================================================== */

.wp-block-button.is-style-plinthworks-pill .wp-block-button__link {
	border-radius: var(--wp--custom--radius--pill, 9999px);
}

/* ==========================================================================
   Block style: Square (button)
   is-style-plinthworks-square — hard 0px corners.

   theme.json sets every button to the pill radius on `elements.button`, so a
   squared button has to override that rather than simply omit a radius. The
   `!important` is needed because a per-block radius set in the editor's Border
   panel is emitted as an inline style, which would otherwise silently win and
   leave the style doing nothing on exactly the blocks someone had customised.
   ========================================================================== */

.wp-block-button.is-style-plinthworks-square .wp-block-button__link,
.wp-block-button.is-style-plinthworks-square .wp-element-button {
	border-radius: var(--wp--custom--radius--none, 0) !important;
}

/* ==========================================================================
   Block style: Highlighted (paragraph)
   is-style-plinthworks-highlighted — left-border accent highlight.
   ========================================================================== */

.wp-block-paragraph.is-style-plinthworks-highlighted {
	border-left: 4px solid var(--wp--preset--color--accent, currentColor);
	padding-left: var(--wp--preset--spacing--50, 1.25rem);
	font-style: italic;
}

/* ==========================================================================
   Block style: Lead (paragraph)
   is-style-plinthworks-lead — larger, softer intro paragraph.
   ========================================================================== */

.wp-block-paragraph.is-style-plinthworks-lead {
	font-size: var(--wp--preset--font-size--large, 1.125rem);
	color: var(--wp--preset--color--contrast-2, #6F6F6F);
	line-height: 1.7;
}

/* ==========================================================================
   Block style: Citation (separator)
   is-style-plinthworks-squiggle — decorative SVG squiggle separator.
   (Fallback to dots if the background-image cannot load.)
   ========================================================================== */

.wp-block-separator.is-style-plinthworks-dotted {
	border: none;
	height: auto;
	text-align: center;
	overflow: visible;
}

.wp-block-separator.is-style-plinthworks-dotted::before {
	content: '· · ·';
	display: block;
	font-size: 1.5em;
	letter-spacing: 0.5em;
	color: var(--wp--preset--color--contrast-3, #727272);
}

/* ==========================================================================
   Block styles: Wide separator and Gradient line
   is-style-plinthworks-wide, is-style-plinthworks-gradient-line

   Phase 4 audit. Both were broken, in two different ways:

   - "Wide" carried `max-width: 100%; width: 100%` in theme.json's variation
     `css` field. theme.json emits that at `:root :where(.wp-block-separator
     .is-style-plinthworks-wide)`, which is (0,1,0), and core ships
     `.wp-block-separator:not(.is-style-wide):not(.is-style-dots){width:100px}`
     at (0,3,0). Core won on every page and the variation did nothing. The
     values are here now, at (0,4,0), so specificity decides rather than load
     order — see PHASE-BRIEFS trap 3.

   - "Gradient line" was registered in the editor's style picker and had no
     rule anywhere: not in theme.json, not in any stylesheet. It rendered as a
     plain 100px hairline. It draws the gradient its name promises now.
   ========================================================================== */

.wp-block-separator.is-style-plinthworks-wide:not(.is-style-wide):not(.is-style-dots) {
	inline-size: 100%;
	max-inline-size: 100%;
}

.wp-block-separator.is-style-plinthworks-gradient-line:not(.is-style-wide):not(.is-style-dots) {
	inline-size: 100%;
	max-inline-size: 100%;
	block-size: 2px;
	border: 0;
	background-image: linear-gradient(
		90deg,
		transparent,
		var(--wp--preset--color--accent, currentColor),
		transparent
	);
}

/* ==========================================================================
   Block style: Plain quote
   is-style-plinthworks-plain

   Phase 4 audit. Same shape as "Wide" above: the variation asked for
   `border: none; padding-left: 0` through theme.json's `css` field, which
   emits at (0,1,0), and plinthworks.css's own `.wp-block-quote` rule at
   (0,1,0) loads later and won. The quote kept its 3px accent rule and its
   40px indent, which is the exact opposite of "plain".
   ========================================================================== */

.wp-block-quote.is-style-plinthworks-plain {
	border: none;
	padding-inline-start: 0;
}

/* ==========================================================================
   Micro-interactions
   ========================================================================== */

/* Smooth focus ring on interactive elements */
:focus-visible {
	/* Two-tone ring: the dark stroke reads on a light ground, the white
	   backing reads on a dark one. Accent is 1.67:1 on white and was
	   effectively invisible. */
	outline: 3px solid var(--wp--preset--color--surface-deep, #343877);
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var(--wp--preset--color--base, #ffffff);
	border-radius: 2px;
}

/* Animated underline on links within content areas */
.entry-content a:not([class]),
.wp-block-post-content a:not([class]) {
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	transition: text-decoration-thickness var(--wp--custom--transition--fast, 0.15s) ease;
}

.entry-content a:not([class]):hover,
.wp-block-post-content a:not([class]):hover {
	text-decoration-thickness: 2px;
}

/* Button hover lift */
.wp-element-button,
.wp-block-button__link {
	transition:
		transform        120ms ease,
		box-shadow       120ms ease,
		background-color 120ms ease,
		color            120ms ease,
		border-color     120ms ease;
}

.wp-element-button:hover,
.wp-block-button__link:hover {
	transform: translateY(-2px);
}

.wp-element-button:active,
.wp-block-button__link:active {
	transform: translateY(0);
	box-shadow: none;
}

/* ==========================================================================
   Scroll reveal — auto-applied by reveal.js + the per-block Animation panel.

   Elements are hidden ONLY under `.pw-reveal-on`, a class an inline <head>
   script adds to <html> before first paint (so there is no flash-then-hide),
   with a failsafe that removes it if reveal.js never runs — so content is never
   stuck hidden, and with JS off nothing is hidden at all. reveal.js adds
   .is-revealed as each element enters the viewport.
   ========================================================================== */

.pw-reveal-on [data-reveal],
.pw-reveal-on .js-reveal {
	opacity: 0;
	transition:
		opacity   0.7s cubic-bezier(0.16, 1, 0.3, 1),
		transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
	transition-delay: var(--reveal-delay, 0ms);
	will-change: opacity, transform;
}

.pw-reveal-on [data-reveal="up"],
.pw-reveal-on .js-reveal      { transform: translateY(36px); }
.pw-reveal-on [data-reveal="fade"]  { transform: none; }
.pw-reveal-on [data-reveal="card"]  { transform: translateY(28px) scale(0.97); }
.pw-reveal-on [data-reveal="down"]  { transform: translateY(-36px); }
.pw-reveal-on [data-reveal="left"]  { transform: translateX(-44px); }
.pw-reveal-on [data-reveal="right"] { transform: translateX(44px); }
.pw-reveal-on [data-reveal="zoom"]  { transform: scale(0.9); }

.pw-reveal-on [data-reveal].is-revealed,
.pw-reveal-on .js-reveal.is-revealed {
	opacity: 1;
	transform: none;

	/*
	 * Hand the element back to normal painting once it has played.
	 *
	 * `will-change` above is never cleared by reveal.js, so without this every
	 * revealed element keeps its own GPU compositing layer for the life of the
	 * page. A promoted layer has its bounds snapped to whole device pixels,
	 * so at fractional scroll offsets the layer edge and the element's real
	 * edge disagree by a fraction of a pixel — and the container's background
	 * shows through underneath the image as a thin grey strip that flickers
	 * while scrolling. Most visible on the student card photos, whose
	 * placeholder background is base-2 (#f7f7f5).
	 *
	 * The hint is only needed WHILE the transition runs, and browsers promote
	 * an element with a running transform/opacity transition on their own, so
	 * releasing it here costs nothing and de-promotes the layer the moment the
	 * reveal finishes. It also stops the page accumulating one permanent layer
	 * per revealed element.
	 */
	will-change: auto;
}

/* Reduced motion: keep a gentle opacity fade (no movement) so the site still
   comes alive without any vestibular motion — never a dead, static page. */
@media (prefers-reduced-motion: reduce) {
	.pw-reveal-on [data-reveal],
	.pw-reveal-on .js-reveal {
		transform: none !important;
		transition: opacity 0.5s ease;
		transition-delay: var(--reveal-delay, 0ms);
	}
}

/* ==========================================================================
   Hero entrance — staggered children of full-width cover inner groups
   Fires on page load (not scroll-triggered) for above-fold impact.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

	.wp-block-cover.alignfull .wp-block-cover__inner-container .wp-block-group > * {
		animation: plinthworks-hero-in 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
	}

	.wp-block-cover.alignfull .wp-block-cover__inner-container .wp-block-group > *:nth-child(1) { animation-delay: 0.1s; }
	.wp-block-cover.alignfull .wp-block-cover__inner-container .wp-block-group > *:nth-child(2) { animation-delay: 0.25s; }
	.wp-block-cover.alignfull .wp-block-cover__inner-container .wp-block-group > *:nth-child(3) { animation-delay: 0.4s; }
	.wp-block-cover.alignfull .wp-block-cover__inner-container .wp-block-group > *:nth-child(4) { animation-delay: 0.55s; }
	.wp-block-cover.alignfull .wp-block-cover__inner-container .wp-block-group > *:nth-child(5) { animation-delay: 0.65s; }

	@keyframes plinthworks-hero-in {
		from {
			opacity: 0;
			transform: translateY(22px);
		}
		to {
			opacity: 1;
			transform: none;
		}
	}
}

/* ==========================================================================
   Cover parallax — background moves on scroll via --parallax-offset CSS var
   set by reveal.js. Only applies to covers with actual image backgrounds.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

	.wp-block-cover.alignfull {
		overflow: hidden;
	}

	.wp-block-cover.alignfull .wp-block-cover__image-background,
	.wp-block-cover.alignfull .wp-block-cover__video-background {
		will-change: transform;
		transform: translateY( var(--parallax-offset, 0px) ) scale(1.12);
	}
}

/* ==========================================================================
   Card hover — lift + shadow
   ========================================================================== */

.wp-block-group.is-style-plinthworks-card,
.wp-block-group.is-style-plinthworks-card-bordered {
	transition:
		box-shadow 0.25s ease,
		transform  0.25s ease;
}

.wp-block-group.is-style-plinthworks-card:hover,
.wp-block-group.is-style-plinthworks-card-bordered:hover {
	box-shadow: 0 12px 36px -8px rgba(0, 0, 0, 0.16);
	transform: translateY(-4px);
}

/* ==========================================================================
   Image hover — zoom within clip
   ========================================================================== */

.wp-block-image:not(.is-style-plinthworks-polaroid) figure {
	overflow: hidden;
	border-radius: inherit;
}

.wp-block-image:not(.is-style-plinthworks-polaroid) img {
	display: block;
	width: 100%;
	transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}

.wp-block-image:not(.is-style-plinthworks-polaroid):hover img {
	transform: scale(1.05);
}

/* ==========================================================================
   Navigation — smooth colour transition on hover
   ========================================================================== */

.wp-block-navigation a {
	transition: color 120ms ease, opacity 120ms ease;
}


/* ==========================================================================
   Separator fade-in — decorative separators appear with a subtle fade
   ========================================================================== */

.wp-block-separator {
	transition: opacity 0.6s ease;
}

/* ==========================================================================
   Background patterns — faded decorative textures on group blocks.
   All patterns use semi-transparent values so they work on any background
   colour without obscuring content. The ::before sits behind content via
   isolation: isolate + z-index: -1 so it never blocks pointer events.
   ========================================================================== */

.wp-block-group[class*="is-style-plinthworks-pattern-"] {
	isolation: isolate;
	position: relative;
}

.wp-block-group[class*="is-style-plinthworks-pattern-"]::before {
	content: '';
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: -1;
	border-radius: inherit;
}

/* Dots — uniform radial dot grid */
.wp-block-group.is-style-plinthworks-pattern-dots::before {
	background-image: radial-gradient(circle, rgba(0, 0, 0, 0.14) 1.5px, transparent 1.5px);
	background-size: 22px 22px;
}

/* Grid — thin horizontal + vertical lines */
.wp-block-group.is-style-plinthworks-pattern-grid::before {
	background-image:
		linear-gradient(rgba(0, 0, 0, 0.07) 1px, transparent 1px),
		linear-gradient(90deg, rgba(0, 0, 0, 0.07) 1px, transparent 1px);
	background-size: 40px 40px;
}

/* Diagonal — 45° stripe hatching */
.wp-block-group.is-style-plinthworks-pattern-diagonal::before {
	background-image: repeating-linear-gradient(
		-45deg,
		transparent,
		transparent 9px,
		rgba(0, 0, 0, 0.06) 9px,
		rgba(0, 0, 0, 0.06) 10px
	);
}

/* Crosshatch — coarse grid overlaid on fine grid */
.wp-block-group.is-style-plinthworks-pattern-crosshatch::before {
	background-image:
		linear-gradient(rgba(0, 0, 0, 0.06) 1px, transparent 1px),
		linear-gradient(90deg, rgba(0, 0, 0, 0.06) 1px, transparent 1px),
		linear-gradient(rgba(0, 0, 0, 0.03) 1px, transparent 1px),
		linear-gradient(90deg, rgba(0, 0, 0, 0.03) 1px, transparent 1px);
	background-size: 80px 80px, 80px 80px, 20px 20px, 20px 20px;
	background-position: -1px -1px, -1px -1px, -1px -1px, -1px -1px;
}

/* ==========================================================================
   Dark mode — colour scheme override
   Applied via [data-color-scheme="dark"] on <html>. Overrides every
   WordPress preset colour variable so all theme.json-aware blocks recolour
   automatically. accent is lightened for legibility on dark surfaces.
   ========================================================================== */

html {
	color-scheme: light;
}

/* The dark palette is DERIVED from the active light palette at runtime —
   see inc/dark-mode.php. Nothing is hardcoded here on purpose: a new brand
   (or the plinthworks-ngo fork) gets a correct dark scheme automatically.
   Only scheme-dependent, non-colour rules belong below. */

/* Smooth colour transitions on scheme switch */
body,
.wp-block-group,
.wp-block-cover,
.wp-block-columns,
.wp-block-column,
.wp-block-navigation,
.wp-block-header-group,
.wp-block-template-part {
	transition:
		background-color 0.35s ease,
		color            0.35s ease,
		border-color     0.35s ease;
}

/* Invert background-pattern dots/lines so they stay subtle in dark mode */
[data-color-scheme="dark"] .wp-block-group.is-style-plinthworks-pattern-dots::before {
	background-image: radial-gradient(circle, rgba(255,255,255,0.12) 1.5px, transparent 1.5px);
}
[data-color-scheme="dark"] .wp-block-group.is-style-plinthworks-pattern-grid::before {
	background-image:
		linear-gradient(rgba(255,255,255,0.07) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255,255,255,0.07) 1px, transparent 1px);
}
[data-color-scheme="dark"] .wp-block-group.is-style-plinthworks-pattern-diagonal::before {
	background-image: repeating-linear-gradient(
		-45deg,
		transparent,
		transparent 9px,
		rgba(255,255,255,0.05) 9px,
		rgba(255,255,255,0.05) 10px
	);
}
[data-color-scheme="dark"] .wp-block-group.is-style-plinthworks-pattern-crosshatch::before {
	background-image:
		linear-gradient(rgba(255,255,255,0.06) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255,255,255,0.06) 1px, transparent 1px),
		linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
}

/* Card borders — lighten in dark mode */
[data-color-scheme="dark"] .wp-block-group.is-style-plinthworks-card {
	border-color: rgba(255,255,255,0.08);
}

/* ==========================================================================
   Dark mode toggle button
   Injected by dark-mode.js. Two variants:
     .pw-dark-toggle--nav    appended inside .wp-block-navigation
     .pw-dark-toggle--fixed  fallback, anchored top-right of viewport
   ========================================================================== */

#pw-dark-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border-radius: 50%;
	border: 1.5px solid currentColor;
	background: transparent;
	color: inherit;
	cursor: pointer;
	opacity: 0.55;
	flex-shrink: 0;
	transition:
		opacity      0.2s ease,
		background   0.2s ease,
		border-color 0.2s ease;
}

#pw-dark-toggle:hover,
#pw-dark-toggle:focus-visible {
	opacity: 1;
}

#pw-dark-toggle svg {
	display: block;
	pointer-events: none;
}

/* When in the nav block — adds spacing from the last nav item */
#pw-dark-toggle.pw-dark-toggle--nav {
	margin-left: 10px;
}

/* Fixed floating button — bottom-right corner */
#pw-dark-toggle.pw-dark-toggle--fixed {
	position: fixed;
	bottom: 28px;
	right: 28px;
	z-index: 9999;
	width: 44px;
	height: 44px;
	background-color: var(--wp--preset--color--base, #fff);
	border-color: var(--wp--preset--color--base-3, #C8C8C8);
	box-shadow:
		0 4px 12px rgba(0, 0, 0, 0.14),
		0 1px 4px  rgba(0, 0, 0, 0.08);
	opacity: 1;
	transition:
		transform     0.2s cubic-bezier(0.16, 1, 0.3, 1),
		box-shadow    0.2s ease,
		background    0.2s ease,
		border-color  0.2s ease;
}

#pw-dark-toggle.pw-dark-toggle--fixed:hover {
	transform: translateY(-3px) scale(1.06);
	box-shadow:
		0 8px 24px rgba(0, 0, 0, 0.18),
		0 2px 6px  rgba(0, 0, 0, 0.1);
}

[data-color-scheme="dark"] #pw-dark-toggle.pw-dark-toggle--fixed {
	background-color: var(--wp--preset--color--base-2, #F9F7F6);
	border-color: var(--wp--preset--color--base-3, #C8C8C8);
	box-shadow:
		0 4px 12px rgba(0, 0, 0, 0.5),
		0 1px 4px  rgba(0, 0, 0, 0.3);
}

/* Remove default focus ring — we handle it via :focus-visible */
#pw-dark-toggle:focus {
	outline: none;
}

#pw-dark-toggle:focus-visible {
	outline: 3px solid var(--wp--preset--color--surface-deep, #343877);
	outline-offset: 3px;
	box-shadow: 0 0 0 6px var(--wp--preset--color--base, #ffffff);
}

/* ==========================================================================
   Visual polish — Squarespace / Elementor quality refinements
   ========================================================================== */

/* Smooth page scrolling */
html {
	scroll-behavior: smooth;
}

/* Brand-colour text selection */
::selection {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
}

/* Heading letter-spacing is set in theme.json (-0.04em on h1-h3, 0 below).
   The blanket -0.02em that stood here overrode it on every heading. */

/* ── Navigation ──────────────────────────────────────────────────────────── */

/* Slide-in underline replaces the blunt opacity change */
.wp-block-navigation .wp-block-navigation-item__content {
	position: relative;
}

.wp-block-navigation .wp-block-navigation-item__content::after {
	content: '';
	position: absolute;
	bottom: -2px;
	left: 0;
	right: 0;
	height: 2px;
	background-color: var(--wp--preset--color--accent);
	border-radius: 1px;
	transform: scaleX(0);
	transform-origin: right center;
	transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.wp-block-navigation .wp-block-navigation-item:hover > .wp-block-navigation-item__content::after,
.wp-block-navigation .current-menu-item > .wp-block-navigation-item__content::after {
	transform: scaleX(1);
	transform-origin: left center;
}

/* ── Site logo ───────────────────────────────────────────────────────────── */

.wp-block-site-logo img {
	transition:
		opacity 0.2s ease,
		transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.wp-block-site-logo a:hover img {
	opacity: 0.78;
	transform: scale(0.96);
}

/* ── Card bordered — base + improved hover ───────────────────────────────── */

.wp-block-group.is-style-plinthworks-card-bordered {
	border: 1.5px solid var(--wp--preset--color--base-3, #C8C8C8);
	border-radius: var(--wp--custom--radius--medium, 8px);
	background-color: var(--wp--preset--color--base);
	transition:
		box-shadow   0.3s cubic-bezier(0.16, 1, 0.3, 1),
		transform    0.3s cubic-bezier(0.16, 1, 0.3, 1),
		border-color 0.3s ease;
}

.wp-block-group.is-style-plinthworks-card-bordered:hover {
	border-color: var(--wp--preset--color--accent);
	box-shadow: 0 24px 64px -20px rgba(0, 0, 0, 0.18);
	transform: translateY(-6px);
}

.wp-block-group.is-style-plinthworks-card:hover {
	box-shadow:
		0 20px 60px -16px rgba(0, 0, 0, 0.18),
		0 0 0 1px rgba(0, 0, 0, 0.04);
}

[data-color-scheme="dark"] .wp-block-group.is-style-plinthworks-card-bordered:hover {
	border-color: rgba(74, 159, 232, 0.6);
}

/* Ghost button is a soft-tint pill (see the block-style section above); no
   separate animated-underline treatment — keeps all button presets one size. */

/* ── Blockquote ──────────────────────────────────────────────────────────── */

.wp-block-quote {
	border-left: 3px solid var(--wp--preset--color--accent);
	padding-left: var(--wp--preset--spacing--60, 2rem);
}

.wp-block-quote p {
	font-size: clamp(1.05rem, 2vw, 1.2rem);
	line-height: 1.65;
	font-style: italic;
}

.wp-block-quote cite,
.wp-block-quote .wp-block-quote__citation {
	display: block;
	margin-top: 0.75em;
	font-size: var(--wp--preset--font-size--small);
	font-style: normal;
	color: var(--wp--preset--color--contrast-3);
}

/* ── Pull quote ──────────────────────────────────────────────────────────── */

.wp-block-pullquote {
	border-color: var(--wp--preset--color--accent);
	border-width: 3px;
	padding: var(--wp--preset--spacing--70, 2.5rem) var(--wp--preset--spacing--60, 2rem);
}

.wp-block-pullquote blockquote p {
	font-size: clamp(1.3rem, 2.5vw, 2rem);
	line-height: 1.35;
	letter-spacing: -0.02em;
}

.wp-block-pullquote .wp-block-pullquote__citation {
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.65;
}

/* ── Image captions ──────────────────────────────────────────────────────── */

.wp-block-image figcaption,
.wp-block-gallery .blocks-gallery-caption {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--contrast-3);
	text-align: center;
	margin-top: 0.6em;
	font-style: italic;
	line-height: 1.4;
}

/* ── Form fields ─────────────────────────────────────────────────────────── */

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="search"],
input[type="number"],
input[type="password"],
textarea,
select {
	border-radius: var(--wp--custom--radius--small, 4px);
	border: 1.5px solid var(--wp--preset--color--base-3, #C8C8C8);
	padding: 0.65em 0.9em;
	background-color: var(--wp--preset--color--base, #fff);
	color: var(--wp--preset--color--contrast, #515266);
	width: 100%;
	font-family: inherit;
	font-size: inherit;
	line-height: 1.5;
	-webkit-appearance: none;
	appearance: none;
	transition:
		border-color 0.2s ease,
		box-shadow   0.2s ease;
}

input[type="text"]:focus,
input[type="email"]:focus,
input[type="tel"]:focus,
input[type="url"]:focus,
input[type="search"]:focus,
input[type="number"]:focus,
input[type="password"]:focus,
textarea:focus,
select:focus {
	outline: 2px solid var(--wp--preset--color--surface-deep, #343877);
	outline-offset: 1px;
	border-color: var(--wp--preset--color--surface-deep, #343877);
	box-shadow: 0 0 0 3.5px rgba(52, 56, 119, 0.14);
}

[data-color-scheme="dark"] input[type="text"],
[data-color-scheme="dark"] input[type="email"],
[data-color-scheme="dark"] input[type="tel"],
[data-color-scheme="dark"] input[type="url"],
[data-color-scheme="dark"] input[type="search"],
[data-color-scheme="dark"] input[type="number"],
[data-color-scheme="dark"] input[type="password"],
[data-color-scheme="dark"] textarea,
[data-color-scheme="dark"] select {
	border-color: rgba(255, 255, 255, 0.12);
	background-color: rgba(255, 255, 255, 0.06);
	color: var(--wp--preset--color--contrast);
}

/* ── Table ───────────────────────────────────────────────────────────────── */

.wp-block-table table {
	width: 100%;
	border-collapse: collapse;
}

.wp-block-table th,
.wp-block-table td {
	padding: 0.75em 1em;
	border: 1px solid var(--wp--preset--color--base-3);
	text-align: left;
	vertical-align: top;
}

.wp-block-table thead th {
	background-color: var(--wp--preset--color--base-2);
	font-weight: 600;
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast-2);
}

.wp-block-table tbody tr {
	transition: background-color 0.15s ease;
}

.wp-block-table tbody tr:hover td {
	background-color: var(--wp--preset--color--base-2);
}

/* ── Post archive / blog ─────────────────────────────────────────────────── */

.wp-block-post-title a {
	text-decoration: none;
	transition: color 0.2s ease;
}

.wp-block-post-title a:hover {
	color: var(--wp--preset--color--surface-deep);
}

/* ── Pagination ──────────────────────────────────────────────────────────── */

.wp-block-query-pagination a,
.wp-block-query-pagination-numbers a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.5em;
	height: 2.5em;
	padding: 0 0.75em;
	border-radius: var(--wp--custom--radius--small);
	border: 1.5px solid var(--wp--preset--color--base-3);
	text-decoration: none;
	font-weight: 500;
	font-size: var(--wp--preset--font-size--small);
	transition:
		background-color 0.2s ease,
		border-color     0.2s ease,
		color            0.2s ease,
		transform        0.2s ease;
}

.wp-block-query-pagination a:hover,
.wp-block-query-pagination-numbers a:hover {
	background-color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--on-action);
	transform: translateY(-2px);
}

.wp-block-query-pagination-numbers .current {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.5em;
	height: 2.5em;
	padding: 0 0.75em;
	border-radius: var(--wp--custom--radius--small);
	border: 1.5px solid var(--wp--preset--color--accent);
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--on-action);
	font-weight: 700;
	font-size: var(--wp--preset--font-size--small);
}

/* ── Gradient heading block style ────────────────────────────────────────── */

.is-style-plinthworks-gradient-heading.wp-block-heading {
	background: linear-gradient(
		135deg,
		var(--wp--preset--color--accent, #EFC940) 0%,
		var(--wp--preset--color--accent-2, #E9BA13) 100%
	);
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	background-clip: text;
}

/* ── Footer link hover ───────────────────────────────────────────────────── */

.wp-block-template-part a:not(.wp-block-button__link):not(.wp-element-button) {
	transition: opacity 0.2s ease;
}

.wp-block-template-part a:not(.wp-block-button__link):not(.wp-element-button):hover {
	opacity: 0.7;
}

/* ==========================================================================
   Sticky header — frosted glass
   The first template part (header) sticks to the viewport top. The inner
   header group has no explicit background so backdrop-filter shows through.
   .is-scrolled is toggled by reveal.js when scrollY > 8px.
   ========================================================================== */

.wp-site-blocks > .wp-block-template-part:first-child {
	position: sticky;
	top: 0;
	z-index: 100;
	-webkit-backdrop-filter: blur(20px) saturate(1.5);
	backdrop-filter: blur(20px) saturate(1.5);
	background-color: var(--wp--preset--color--base);
	transition: box-shadow 0.3s ease;
}

/* On mobile (≤ 599px) we strip backdrop-filter for two reasons:
   1. It creates a containing block for position:fixed children, which the nav
      overlay needs to escape (the overlay opens at root level, not nested).
   2. The blur is wasted compute on small screens and the solid base background
      gives a cleaner, more readable strip.
   z-index stays at 100 so the header reliably paints above page content
   (covers, hero sections, reveal-animated cards). The stacking-context issue
   that used to trap the overlay at z-index 100 is solved separately by the
   `html.has-modal-open` rule below — when the drawer opens, the header is
   forced to `position:static; z-index:auto`, dissolving the stacking context
   so the overlay participates at root z-index 100000. */
/* The cut-off must match the range where a fixed-position drawer exists, NOT a
   guess about screen size. The mega-nav drawer takes over at ≤920px, and while
   this was capped at 599px the 600-920px band was broken: the drawer anchored
   to the header strip instead of the viewport, so it opened as an unusable
   sliver. Desktop and phone worked, tablet did not. Keep these two numbers in
   step: mega-nav/style.css opens the drawer at the same 920px. */
@media (max-width: 920px) {
	.wp-site-blocks > .wp-block-template-part:first-child {
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
	}
}

.wp-site-blocks > .wp-block-template-part:first-child header.wp-block-group:not(.has-background) {
	background-color: transparent;
}

/* Mobile header — force solid background at the wrapper AND inner header.
   Without this, the desktop backdrop-filter blur makes the strip read as solid;
   removing the blur on mobile (above) exposes the desktop's translucent feel
   from the cascade. Explicit !important here pins it to the base preset colour,
   which is opaque in both light and dark modes (#ffffff / #0d0d0d). */
@media (max-width: 767px) {
	.wp-site-blocks > .wp-block-template-part:first-child,
	.wp-site-blocks > .wp-block-template-part:first-child > header.wp-block-group {
		background-color: var(--wp--preset--color--base, #fff) !important;
	}
}

.wp-site-blocks > .wp-block-template-part:first-child.is-scrolled {
	/* Thick contrast-coloured line + soft drop shadow for depth.
	   `0 3px 0` paints a hard 3 px line flush with the header's bottom edge —
	   no layout shift (it's a shadow, not a border). The contrast preset flips
	   to a near-white in dark mode automatically. */
	box-shadow:
		0 3px 0       var(--wp--preset--color--contrast, #515266),
		0 6px 16px -6px rgba(0, 0, 0, 0.14);
}

/* Tight header → hero junction.
   WP block themes apply `.wp-site-blocks > * { margin-block-start: 24px }` to
   every root-level block, which inserts a 24 px gap below the header. For the
   block immediately after the header template-part — typically a hero / cover /
   archive band — flush is the expected look. */
.wp-site-blocks > .wp-block-template-part:first-child + * {
	margin-block-start: 0;
}

[data-color-scheme="dark"] .wp-site-blocks > .wp-block-template-part:first-child {
	border-bottom-color: rgba(255, 255, 255, 0.06);
}

/* ==========================================================================
   Page hero — featured image cover with diagonal stripe pattern
   Used via parts/page-hero.html on all singular templates except front-page.
   ========================================================================== */

.wp-block-cover.pw-page-hero {
	margin-block-end: 0;
}

.wp-block-cover.pw-page-hero::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 2;
	background-image: repeating-linear-gradient(
		-45deg,
		transparent 0,
		transparent 3px,
		rgba(255, 255, 255, 0.025) 3px,
		rgba(255, 255, 255, 0.025) 4px
	);
	pointer-events: none;
}

.wp-block-cover.pw-page-hero .wp-block-cover__inner-container {
	position: relative;
	z-index: 3;
}

/* ==========================================================================
   Archive hero — solid accent background with diagonal stripe pattern
   Used inline in all archive / taxonomy / search templates.
   ========================================================================== */

/* ==========================================================================
   Full width has to actually reach the edge, everywhere

   There are two ways a template can silently break the editor's "Full width"
   toggle, and this theme had both:

   1. A `wp:post-content` without `align:full` is width-capped like any other
      child of a constrained wrapper, so nothing inside it can ever escape.
      Fixed in the templates themselves.

   2. A wrapper that caps width in CSS rather than by layout. The CPT profile
      surfaces (.mhm-program, .mhm-cause, .mhm-profile) set max-width in the
      plugin stylesheet, which no block attribute can see or override. An
      author toggles Full width, the block gets .alignfull, and nothing moves.

   This rule fixes the second case generally: inside those surfaces, anything
   marked alignfull breaks out to the viewport. It is written against
   .alignfull rather than a list of blocks, so a component added next year
   behaves correctly without being named here.
   ========================================================================== */

.mhm-program .alignfull,
.mhm-cause .alignfull,
.mhm-profile .alignfull,
.mhm-program__story .alignfull,
.mhm-cause__story .alignfull,
.mhm-profile__story .alignfull {
	width:         100vw;
	max-width:     100vw;
	margin-inline: calc(50% - 50vw);
}

/* alignwide inside the same surfaces: widen to the theme's wide size rather
   than the narrow reading measure, without going edge to edge. */
.mhm-program .alignwide,
.mhm-cause .alignwide,
.mhm-profile .alignwide,
.mhm-program__story .alignwide,
.mhm-cause__story .alignwide,
.mhm-profile__story .alignwide {
	width:         min(var(--wp--style--global--wide-size, 1340px), 100vw);
	max-width:     min(var(--wp--style--global--wide-size, 1340px), 100vw);
	margin-inline: auto;
}

/* A full-bleed child must never hand the page a horizontal scrollbar. This
   CANNOT go on .mhm-program and friends: they are the very boxes the breakout
   escapes from, so clipping there would clip the thing we just released. It
   belongs on the page root, where it catches the sliver that 100vw overshoots
   by when a vertical scrollbar is present, and nothing else.

   `clip` rather than `hidden` on purpose: `hidden` on an ancestor turns the
   element into a scroll container, which breaks the sticky header. */
.wp-site-blocks {
	overflow-x: clip;
}

/* ==========================================================================
   Intro hero with a photo stack
   The opener used across page designs: eyebrow, headline with a highlighted
   phrase, lead, actions, and a leaning pair of photographs on the right with a
   floating stat chip and a caption chip.

   Everything here is plain core blocks wearing these classes, so the whole
   thing stays editable in the block editor. The stack is CSS: the editor never
   sees a rotation control it has to understand, and a site that swaps the
   photos keeps the composition.
   ========================================================================== */

.pw-intro {
	position: relative;
	overflow: hidden;
	background:
		radial-gradient(ellipse at 82% 12%, color-mix(in srgb, var(--wp--preset--color--accent-2, #E9BA13) 26%, transparent) 0%, transparent 62%),
		radial-gradient(ellipse at 8% 88%, color-mix(in srgb, var(--wp--preset--color--accent-3, #F36F8F) 20%, transparent) 0%, transparent 58%),
		var(--wp--preset--color--base-2, #F9F7F6);
}

/* Eyebrow: a short rule, then the label. */
.pw-intro__eyebrow {
	display:        flex;
	align-items:    center;
	gap:            12px;
	font-size:      0.78rem;
	font-weight:    700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color:          var(--wp--preset--color--contrast-3, #727272);
}

.pw-intro__eyebrow::before {
	content:       '';
	width:         28px;
	height:        2px;
	flex:          none;
	background:    currentColor;
	border-radius: 2px;
}

/* The highlighted phrase in the headline: a soft band behind the words, sitting
   under the text rather than over it. */
.pw-intro mark,
.pw-intro .pw-intro__mark {
	background:  none;
	color:       var(--wp--preset--color--contrast, #515266);
	position:    relative;
	white-space: nowrap;
}

.pw-intro mark::after,
.pw-intro .pw-intro__mark::after {
	content:       '';
	position:      absolute;
	left:          -0.06em;
	right:         -0.06em;
	bottom:        0.02em;
	height:        0.32em;
	z-index:       -1;
	border-radius: 3px;
	background:    color-mix(in srgb, var(--wp--preset--color--accent-2, #E9BA13) 62%, transparent);
}

/* ── The photo stack ─────────────────────────────────────────────────────── */

.pw-photo-stack {
	position:  relative;
	min-height: 420px;
}

.pw-photo-stack .wp-block-image {
	margin: 0;
}

.pw-photo-stack .wp-block-image img {
	display:       block;
	width:         100%;
	height:        100%;
	object-fit:    cover;
	border-radius: 18px;
}

/* Back plate: the larger, calmer one. */
.pw-photo-stack .wp-block-image:nth-of-type(1) {
	position:  relative;
	width:     78%;
	aspect-ratio: 4 / 3;
	transform: rotate(-1.6deg);
	box-shadow: 0 18px 44px rgba(63, 42, 36, 0.13);
	border-radius: 18px;
	overflow: hidden;
}

/* Front plate: overlaps the corner, with a light edge so it separates cleanly. */
.pw-photo-stack .wp-block-image:nth-of-type(2) {
	position:  absolute;
	right:     0;
	bottom:    -18px;
	width:     46%;
	aspect-ratio: 3 / 4;
	transform: rotate(2.2deg);
	border:    6px solid var(--wp--preset--color--base, #fff);
	border-radius: 20px;
	overflow:  hidden;
	box-shadow: 0 16px 40px rgba(63, 42, 36, 0.16);
}

/* Floating chips. Paragraphs in the markup, so they stay editable. */
.pw-photo-stack__badge,
.pw-photo-stack__caption {
	position:      absolute;
	z-index:       3;
	margin:        0;
	display:       inline-flex;
	align-items:   center;
	gap:           8px;
	background:    var(--wp--preset--color--base, #fff);
	border-radius: 999px;
	font-size:     0.86rem;
	line-height:   1.3;
	box-shadow:    0 8px 24px rgba(63, 42, 36, 0.12);
}

.pw-photo-stack__badge {
	top:     6%;
	left:    -6%;
	padding: 10px 18px 10px 12px;
	font-weight: 600;
	color:   var(--wp--preset--color--contrast, #515266);
}

.pw-photo-stack__badge::before {
	content:         '';
	width:           26px;
	height:          26px;
	flex:            none;
	border-radius:   50%;
	background:      color-mix(in srgb, var(--wp--preset--color--accent-3, #F36F8F) 45%, transparent);
}

.pw-photo-stack__caption {
	left:       2%;
	bottom:     8%;
	padding:    8px 16px;
	font-size:  0.8rem;
	color:      var(--wp--preset--color--contrast-2, #6F6F6F);
}

.pw-photo-stack__caption::before {
	content:       '';
	width:         7px;
	height:        7px;
	flex:          none;
	border-radius: 50%;
	background:    var(--wp--preset--color--accent, #EFC940);
}

/* Mobile: the lean and the overlap stop being charming once there is no room
   for them, so the stack becomes an honest single photo. */
@media (max-width: 781px) {
	.pw-photo-stack {
		min-height: 0;
		margin-top: var(--wp--preset--spacing--50, 32px);
	}
	.pw-photo-stack .wp-block-image:nth-of-type(1) {
		width:     100%;
		transform: none;
	}
	.pw-photo-stack .wp-block-image:nth-of-type(2) {
		position: relative;
		right:    auto;
		bottom:   auto;
		width:    58%;
		margin:   -14% 0 0 auto;
		transform: rotate(2deg);
	}
	.pw-photo-stack__badge {
		left: 0;
		top:  -14px;
	}
	.pw-photo-stack__caption {
		display: none;   /* no room, and the photo speaks for itself */
	}
}

@media (prefers-reduced-motion: reduce) {
	.pw-photo-stack .wp-block-image:nth-of-type(1),
	.pw-photo-stack .wp-block-image:nth-of-type(2) {
		transform: none;
	}
}

/* ==========================================================================
   Hero titles are always white
   A hero sits on a photograph or on the accent colour, in every scheme. The
   templates said textColor:"base", which is correct in light mode and WRONG the
   moment the palette flips: `base` becomes the dark surface, so the title turned
   near-black on top of a dark photo. Colour here is not a palette decision, it
   is a legibility one, so it is pinned rather than derived.

   !important is needed to beat WordPress's own preset colour classes, which are
   themselves emitted with !important, and the selector is deliberately specific
   enough to beat the dark-mode overrides and the media-ink pass too. The front
   page is untouched: its hero is the slider, which carries none of these
   classes.
   ========================================================================== */

html :is(.mhm-hero, .pw-page-hero, .pw-archive-hero) :is(h1, .wp-block-post-title, .wp-block-query-title),
html[data-color-scheme="dark"] :is(.mhm-hero, .pw-page-hero, .pw-archive-hero) :is(h1, .wp-block-post-title, .wp-block-query-title) {
	color: #ffffff !important;
}

html :is(.mhm-hero, .pw-page-hero, .pw-archive-hero) :is(h1, .wp-block-post-title, .wp-block-query-title) a,
html[data-color-scheme="dark"] :is(.mhm-hero, .pw-page-hero, .pw-archive-hero) :is(h1, .wp-block-post-title, .wp-block-query-title) a {
	color: #ffffff !important;
}

/* One number for hero height across the site. parts/page-hero.html sets the
   same 300px on its cover; keep them in step, or override this variable to
   change every hero at once. */
:root {
	--pw-hero-min-height: 300px;
}

.pw-archive-hero {
	position: relative;
	overflow: hidden;
	margin-block-end: 0;
}

.pw-archive-hero::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image: repeating-linear-gradient(
		-45deg,
		transparent 0,
		transparent 3px,
		rgba(255, 255, 255, 0.025) 3px,
		rgba(255, 255, 255, 0.025) 4px
	);
	pointer-events: none;
}

.pw-archive-hero > .wp-block-group {
	position: relative;
	z-index: 1;
}

/* Archive hero wearing a photo borrowed from the newest entry in the query
   (inc/archive-hero-image.php). The picture sits UNDER a heavy accent scrim:
   the heading has to stay exactly as readable as it was on the solid colour,
   so the photo adds depth rather than competing with the words. With no
   image the class is never added and the flat accent hero remains. */
.pw-archive-hero.has-pw-hero-image {
	background-size:     cover;
	background-position: center;
	background-repeat:   no-repeat;
	display:             flex;
	align-items:         flex-end;
	min-height:          var(--pw-hero-min-height, 300px);
}

/* The same gradient the standard hero uses (parts/page-hero.html): dark at the
   top and bottom edges where the text sits, near-clear through the middle so
   the photograph is actually visible. Not a flat opacity wash over the whole
   picture, which mutes it everywhere including the parts with no text on them. */
.pw-archive-hero.has-pw-hero-image::after {
	content:  '';
	position: absolute;
	inset:    0;
	z-index:  0;
	pointer-events: none;
	background: linear-gradient(
		180deg,
		rgba(20, 28, 38, 0.72)  0%,
		rgba(20, 28, 38, 0.12) 32%,
		rgba(20, 28, 38, 0.14) 55%,
		rgba(20, 28, 38, 0.82) 100%
	);
}

.pw-archive-hero.has-pw-hero-image > .wp-block-group {
	width: 100%;
}

/* The stripe texture belongs on top of the scrim, not under the photo. */
.pw-archive-hero.has-pw-hero-image::before {
	z-index: 1;
}

.pw-archive-hero.has-pw-hero-image > .wp-block-group {
	z-index: 2;
}

/* ==========================================================================
   Breadcrumb strip
   Full-width bar that sits immediately below the hero — no gap between them.
   ========================================================================== */

.wp-block-template-part:has(.pw-breadcrumb-strip) {
	margin-block-start: 0;
}

.pw-breadcrumb-strip {
	border-bottom: 1px solid var(--wp--preset--color--base-3, #C8C8C8);
}

[data-color-scheme="dark"] .wp-site-blocks > .wp-block-template-part:first-child.is-scrolled {
	/* Dark-mode contrast is near-white — first shadow uses the variable so it
	   flips automatically; only the soft glow needs an explicit dark override. */
	box-shadow:
		0 3px 0       var(--wp--preset--color--contrast, #515266),
		0 6px 16px -6px rgba(0, 0, 0, 0.5);
}

/* Anchor targets don't hide under sticky header */
:target {
	scroll-margin-top: 80px;
}

/* ==========================================================================
   Typography — editorial balance and rhythm
   ========================================================================== */

/* text-wrap: balance keeps short heading lines from awkward breaks */
h1, h2, h3,
.wp-block-heading {
	text-wrap: balance;
}

/* Prettier paragraph text wrapping (avoids orphan single words) */
.wp-block-paragraph,
p {
	text-wrap: pretty;
}

/* ==========================================================================
   Images — subtle border-radius for undecorated standalone images
   ========================================================================== */

.wp-block-image:not([class*="is-style-"]) img {
	border-radius: var(--wp--custom--radius--small, 4px);
}

/* ==========================================================================
   Columns — refined stagger (fallback for when reveal.js sets inline delay)
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
	.wp-block-columns .wp-block-column:not([style*="--reveal-delay"]):nth-child(1) [data-reveal] { --reveal-delay:   0ms; }
	.wp-block-columns .wp-block-column:not([style*="--reveal-delay"]):nth-child(2) [data-reveal] { --reveal-delay:  90ms; }
	.wp-block-columns .wp-block-column:not([style*="--reveal-delay"]):nth-child(3) [data-reveal] { --reveal-delay: 180ms; }
	.wp-block-columns .wp-block-column:not([style*="--reveal-delay"]):nth-child(4) [data-reveal] { --reveal-delay: 270ms; }
}

/* ==========================================================================
   Skip-to-content link — accessibility + polished
   ========================================================================== */

.skip-link {
	position: absolute;
	top: -100%;
	left: var(--wp--preset--spacing--50, 2rem);
	padding: 0.6rem 1.25rem;
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
	font-weight: 600;
	font-size: var(--wp--preset--font-size--small);
	border-radius: 0 0 var(--wp--custom--radius--medium) var(--wp--custom--radius--medium);
	text-decoration: none;
	z-index: 9999;
	transition: top 0.2s ease;
}

.skip-link:focus {
	top: 0;
}


/* ==========================================================================
   Hero / cover — text readability
   A subtle text shadow improves legibility on image covers without flattening
   the overall look. Only applies to the inner container children.
   ========================================================================== */

.wp-block-cover.is-dark .wp-block-cover__inner-container .wp-block-heading,
.wp-block-cover.is-dark .wp-block-cover__inner-container .wp-block-paragraph {
	text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35);
}

/* ==========================================================================
   Eyebrow block style — decorative rule before the text
   Only applied when the registered block style class is present.
   ========================================================================== */

.is-style-plinthworks-eyebrow.wp-block-heading {
	display: flex;
	align-items: center;
	gap: 0.65em;
}

.is-style-plinthworks-eyebrow.wp-block-heading::before {
	content: '';
	display: inline-block;
	flex-shrink: 0;
	width: 1.75em;
	height: 2px;
	border-radius: 1px;
	background-color: currentColor;
	opacity: 0.7;
}

/* Right-aligned eyebrow — mirror the layout so the rule sits on the outer edge,
   the same way it does when left-aligned. */
.has-text-align-right.is-style-plinthworks-eyebrow.wp-block-heading {
	flex-direction: row-reverse;
	justify-content: flex-start;
}

/* Centred eyebrow — show rules on both sides */
.has-text-align-center.is-style-plinthworks-eyebrow.wp-block-heading {
	justify-content: center;
}

.has-text-align-center.is-style-plinthworks-eyebrow.wp-block-heading::after {
	content: '';
	display: inline-block;
	flex-shrink: 0;
	width: 1.75em;
	height: 2px;
	border-radius: 1px;
	background-color: currentColor;
	opacity: 0.7;
}

/* ==========================================================================
   Testimonial / big-quote typography — editorial flourish
   The landing page uses a large opening quote mark as a paragraph.
   ========================================================================== */

.wp-block-paragraph[style*="xxx-large"] {
	line-height: 0.8;
	opacity: 0.25;
	user-select: none;
	pointer-events: none;
}

/* ==========================================================================
   Stats — number legibility
   The plinthworks/stats block sets tabular-nums itself; this covers any other
   markup that renders a stat value. (The old [class*="stats-counter"] hooks
   went with the stats-counter block, deleted 2026-08.)
   ========================================================================== */

.plinthworks-stats__value {
	font-variant-numeric: tabular-nums;
	letter-spacing: -0.03em;
}

/* ==========================================================================
   Cover gradient band — bottom fade for better section transition
   Helps content blocks that directly follow a cover feel less abrupt.
   ========================================================================== */

.wp-block-cover.alignfull.is-dark + * {
	margin-top: 0;
}

/* ==========================================================================
   Post meta — smaller, muted, consistent
   ========================================================================== */

.wp-block-post-date,
.wp-block-post-author,
.wp-block-post-terms {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--contrast-3);
}

/* ==========================================================================
   Featured image — consistent sizing in query loops
   ========================================================================== */

.wp-block-post-featured-image img {
	border-radius: var(--wp--custom--radius--small, 4px);
	transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}

.wp-block-post-featured-image:hover img {
	transform: scale(1.04);
}

/* ==========================================================================
   Service card — accent top border on homepage cards (.pw-service-card)
   ========================================================================== */

.pw-service-card {
	border-top: 3px solid var(--wp--preset--color--accent-2) !important;
}

/* Lift accent-2 color on hover to reinforce the orange brand connection */
.pw-service-card:hover {
	border-top-color: var(--wp--preset--color--accent-2) !important;
}

/* ==========================================================================
   Testimonial card — subtle hover glow on the dark accent background
   ========================================================================== */

.pw-testimonial-card {
	transition:
		background-color 0.25s ease,
		border-color     0.25s ease,
		transform        0.25s ease;
}

.pw-testimonial-card:hover {
	background-color: rgba(255, 255, 255, 0.1) !important;
	border-color: rgba(255, 255, 255, 0.22) !important;
	transform: translateY(-4px);
}

/* ==========================================================================
   Primary navigation — desktop dropdown (mega menu)
   Styled here because WordPress block CSS cannot target .pw-primary-nav context.
   ========================================================================== */

.pw-primary-nav .wp-block-navigation__submenu-container {
	min-width: 210px;
	padding: 0.4rem;
	background-color: var(--wp--preset--color--base, #fff);
	border: 1px solid var(--wp--preset--color--base-3, #C8C8C8);
	border-radius: var(--wp--custom--radius--medium, 8px);
	box-shadow:
		0 4px 6px -1px rgba(0, 0, 0, 0.07),
		0 16px 48px -12px rgba(0, 0, 0, 0.14);
	animation: pw-dropdown-in 0.18s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes pw-dropdown-in {
	from { opacity: 0; transform: translateY(-8px); }
	to   { opacity: 1; transform: none; }
}

.pw-primary-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	padding: 0.5rem 0.875rem;
	border-radius: 6px;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--contrast, #515266);
	text-decoration: none;
	white-space: nowrap;
	transition:
		background-color 0.15s ease,
		color            0.15s ease;
}

.pw-primary-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	background-color: var(--wp--preset--color--base-2, #F9F7F6);
	color: var(--wp--preset--color--surface-deep, #343877);
	opacity: 1;
}

/* No slide-in underline inside dropdowns */
.pw-primary-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
	display: none;
}

/* ── Primary nav alignment — flex-grow fills header, items right-justified ── */

.pw-primary-nav {
	flex: 1 1 auto;
	min-width: 0;
}

.pw-primary-nav > .wp-block-navigation__container {
	justify-content: flex-end !important;
	margin-left: auto;
}

/* CTA pill button — never shrinks */
.pw-header-cta {
	flex-shrink: 0;
}

/* Chevron indicator on parent items */
.pw-primary-nav .wp-block-navigation-item.has-child > .wp-block-navigation-item__content .wp-block-navigation-submenu__toggle {
	opacity: 0.45;
	margin-left: 0.3em;
	transition: transform 0.2s ease, opacity 0.2s ease;
}

.pw-primary-nav .wp-block-navigation-item.has-child:hover > .wp-block-navigation-item__content .wp-block-navigation-submenu__toggle,
.pw-primary-nav .wp-block-navigation-item.has-child.open-on-click > .wp-block-navigation-item__content .wp-block-navigation-submenu__toggle {
	opacity: 0.8;
	transform: rotate(180deg);
}

/* ==========================================================================
   Mobile navigation — right-side drawer

   Why the stacking-context fix is needed:
   backdrop-filter on the sticky header creates a containing block for
   position:fixed children (CSS spec). Without removing it, the overlay
   positions itself relative to the header strip, not the viewport.
   WordPress adds "has-modal-open" to <html> (view.js:143), not <body>.

   Drawer layout:
     .wp-block-navigation__responsive-container.is-menu-open
         = full-viewport backdrop (dimmed)
       └─ .wp-block-navigation__responsive-dialog
             = right-side panel (≤ 340 px / 82 vw)
           ├─ .wp-block-navigation__responsive-container-close
           │     = sticky header bar with "Menu" label + close button
           └─ .wp-block-navigation__responsive-close
                 = scrollable nav list

   Accordion: WP's own JS toggles [aria-expanded="true"] on
   .wp-block-navigation-submenu__toggle. That attribute drives the
   expand/collapse via the sibling ~ selector.
   ========================================================================== */

/* ── 1. Dissolve header stacking context / containing block on open ──────── */
/* position:static removes ALL stacking-context/containing-block creation —
   position:sticky with z-index:auto still gets promoted to a GPU layer by
   some mobile browsers (Safari, Chrome) which implicitly creates a stacking
   context, trapping the overlay. position:static can never be a stacking
   context or a containing block for position:fixed. The page is scroll-locked
   (html overflow:hidden) when the modal is open so losing sticky is harmless. */
html.has-modal-open .wp-site-blocks > .wp-block-template-part:first-child {
	position: static !important;
	z-index: auto !important;
	-webkit-backdrop-filter: none !important;
	backdrop-filter: none !important;
}

/* ── 2. Full-viewport backdrop ───────────────────────────────────────────── */
/* transform:translateZ(0) promotes the overlay to its own GPU compositing
   layer, ensuring the browser honours z-index:100000 in GPU layer order even
   when reveal-animated elements (transform:translateY) have been promoted too.
   CSS variable reset: WP uses --navigation-layout-justification-setting for
   align-items on every item in the overlay. The nav block has justifyContent:right
   on desktop, which evaluates to flex-end here — right-aligning and narrowing
   all items. Resetting to stretch propagates through WP's own cascade. */
.wp-block-navigation__responsive-container.is-menu-open {
	position: fixed !important;
	inset: 0 !important;
	z-index: 100000 !important;
	background: rgba(0, 0, 0, 0.54) !important;
	padding: 0 !important;
	overflow: hidden !important;
	animation: none !important;
	transform: translateZ(0);
	--navigation-layout-justification-setting: stretch;
	--navigation-layout-justify: flex-start;
	--navigation-layout-align: stretch;
}

/* ── 3. Drawer panel ─────────────────────────────────────────────────────── */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-dialog {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: auto;
	width: min(340px, 82vw);
	/* Solid background — !important beats WP's background:inherit chain */
	background-color: var(--wp--preset--color--base, #ffffff) !important;
	border-left: 1px solid var(--wp--preset--color--base-3);
	box-shadow: -2px 0 0 rgba(0,0,0,0.04), -16px 0 48px rgba(0,0,0,0.18);
	display: flex;
	flex-direction: column;
	overflow: hidden;
	/* Slide in from right */
	animation: pw-drawer-in 0.28s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes pw-drawer-in {
	from { transform: translateX(100%); }
	to   { transform: translateX(0); }
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-dialog {
		animation: none;
	}
}

/* ── 4. Sticky header bar (close button row) ─────────────────────────────── */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close {
	position: sticky;
	top: 0;
	width: 100%;
	height: 60px;
	padding: 0 1.25rem;
	display: flex !important;
	align-items: center;
	justify-content: space-between;
	background-color: var(--wp--preset--color--base);
	border-bottom: 1px solid var(--wp--preset--color--base-3);
	z-index: 2;
	flex-shrink: 0;
	color: var(--wp--preset--color--contrast);
	opacity: 1;
}

/* "Menu" label on the left of the close bar */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close::before {
	content: "Menu";
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast-3);
}

/* Close icon sizing + hover */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close svg {
	width: 20px;
	height: 20px;
	opacity: 0.55;
	transition: opacity 0.15s ease, transform 0.15s ease;
}

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close:hover svg,
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-close:focus-visible svg {
	opacity: 1;
	transform: scale(1.1);
}

/* ── 5. Scrollable nav body ──────────────────────────────────────────────── */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-close {
	flex: 1;
	overflow-y: auto;
	overflow-x: hidden;
	-webkit-overflow-scrolling: touch;
	padding: 0.25rem 0 2.5rem;
	max-width: none !important;         /* override WP's centered max-width */
	margin: 0 !important;
}

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-content {
	flex-direction: column !important;
	align-items: stretch !important;
	justify-content: flex-start !important;
	gap: 0 !important;
	padding: 0 !important;
	text-align: left !important;
}

/* WP makes every item a column-flex with align-items from the justification
   variable. Reset it here so all items — not just .has-child ones — stretch
   full-width and left-align their content. */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-content .wp-block-navigation-item,
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-content .wp-block-navigation__container,
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-container-content .wp-block-page-list {
	align-items: stretch !important;
	width: 100% !important;
}

/* ── 6. Top-level item rows ──────────────────────────────────────────────── */
/* Override WP's column-flex in the overlay so link + chevron stay in a row,
   while the submenu wraps to a new "line" below via flex-wrap. */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .wp-block-navigation-item {
	flex-direction: row !important;
	flex-wrap: wrap !important;
	align-items: center !important;
	border-bottom: 1px solid var(--wp--preset--color--base-3);
	transition: background-color 0.15s ease;
}

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .wp-block-navigation-item:last-child {
	border-bottom: none;
}

/* Link / toggle button in the row */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .wp-block-navigation-item
> .wp-block-navigation-item__content,
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .wp-block-navigation-item
> .wp-block-navigation-submenu__toggle {
	flex: 1 !important;
	padding: 1rem 0.75rem 1rem 1rem !important;
	font-size: var(--wp--preset--font-size--small, 0.9375rem) !important;
	font-weight: 600;
	color: var(--wp--preset--color--contrast) !important;
	text-decoration: none !important;
	line-height: 1.3;
	background: none;
	border: none;
	text-align: left !important;
	justify-content: flex-start !important;
	display: flex !important;
	align-items: center !important;
}

/* Hover tint */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .wp-block-navigation-item:hover,
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .wp-block-navigation-item:focus-within {
	background-color: var(--wp--preset--color--base-2);
}

/* Active / current page — accent text colour (no left border) */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .wp-block-navigation-item.current-menu-item
> .wp-block-navigation-item__content,
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .wp-block-navigation-item.current-menu-ancestor
> .wp-block-navigation-item__content {
	color: var(--wp--preset--color--surface-deep) !important;
}

/* ── 7. Chevron icon (submenu toggle) ────────────────────────────────────── */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .has-child
> .wp-block-navigation__submenu-icon {
	display: flex !important;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 48px;
	min-height: 48px;
	cursor: pointer;
	color: var(--wp--preset--color--contrast-3);
	transition: color 0.15s ease;
}

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .has-child
> .wp-block-navigation__submenu-icon svg {
	width: 16px;
	height: 16px;
	/* WP already rotates on aria-expanded=true — no extra rule needed */
	transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .has-child
> .wp-block-navigation-submenu__toggle[aria-expanded="true"]
~ .wp-block-navigation__submenu-icon {
	color: var(--wp--preset--color--surface-deep);
}

/* ── 8. Submenu accordion ────────────────────────────────────────────────── */
/* WP forces all submenus visible in .is-menu-open. Override to hide by default
   and reveal only when [aria-expanded="true"] is set by WP's view.js. */

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .has-child
> .wp-block-navigation__submenu-container {
	/* Full width below the link+chevron row */
	width: 100% !important;
	flex-basis: 100% !important;
	order: 99;
	position: static !important;
	/* Collapsed state */
	height: 0 !important;
	overflow: hidden !important;
	opacity: 0 !important;
	visibility: hidden !important;
	padding-top: 0 !important;
	min-width: unset !important;
	transition:
		opacity 0.22s ease,
		visibility 0.22s ease;
}

/* Expanded: toggled by WP's own JS setting aria-expanded="true" */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__container > .has-child
> .wp-block-navigation-submenu__toggle[aria-expanded="true"]
~ .wp-block-navigation__submenu-container {
	height: auto !important;
	overflow: visible !important;
	opacity: 1 !important;
	visibility: visible !important;
}

/* Submenu container background */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container {
	background-color: var(--wp--preset--color--base-2) !important;
	box-shadow: none !important;
	border-radius: 0 !important;
	animation: none !important;
	border-top: 1px solid var(--wp--preset--color--base-3);
}

/* ── 9. Submenu child links ──────────────────────────────────────────────── */
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container > .wp-block-navigation-item {
	flex-direction: row !important;
	align-items: stretch !important;
	border-bottom: 1px solid var(--wp--preset--color--base-3) !important;
}

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container > .wp-block-navigation-item:last-child {
	border-bottom: none !important;
}

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	display: flex !important;
	align-items: center;
	width: 100%;
	padding: 0.8rem 1.25rem 0.8rem 1.25rem !important;
	font-size: var(--wp--preset--font-size--small, 0.875rem) !important;
	font-weight: 500 !important;
	color: var(--wp--preset--color--contrast-2) !important;
	text-decoration: none !important;
	transition: color 0.15s ease, background-color 0.15s ease;
}

.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--contrast) !important;
	background-color: var(--wp--preset--color--base-3) !important;
}

/* ── 10. Hamburger open button — mobile only ─────────────────────────────── */
/* WP already hides this at ≥ 600px via its own @media rule.
   We must not override that with display:flex outside a matching media query. */
@media (max-width: 599px) {
	.wp-block-navigation__responsive-container-open {
		width: 40px;
		height: 40px;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: var(--wp--custom--radius--small, 4px);
		color: var(--wp--preset--color--contrast);
		transition: background-color 0.15s ease;
	}

	.wp-block-navigation__responsive-container-open:hover {
		background-color: var(--wp--preset--color--base-2);
	}

	.wp-block-navigation__responsive-container-open svg {
		width: 22px;
		height: 22px;
	}
}

/* ── 11. Dark mode deepening ─────────────────────────────────────────────── */
/* CSS-variable dark themes (style variations) work automatically above.
   This block handles the JS-toggled [data-color-scheme="dark"] case. */

[data-color-scheme="dark"]
.wp-block-navigation__responsive-container.is-menu-open {
	background: rgba(0, 0, 0, 0.72) !important;
}

[data-color-scheme="dark"]
.wp-block-navigation__responsive-container.is-menu-open
.wp-block-navigation__responsive-dialog {
	box-shadow:
		-1px 0 0 rgba(255, 255, 255, 0.06),
		-16px 0 48px rgba(0, 0, 0, 0.55);
}

/* ==========================================================================
   Dark mode — protect intentionally-dark sections from palette flip
   Blocks that use contrast (dark) or accent (navy) as background must stay
   dark when the light→dark palette swap occurs. We re-establish the correct
   colour tokens locally on these elements.
   ========================================================================== */

/* Full-width sections with contrast (dark) background — always stay dark */
[data-color-scheme="dark"] .alignfull.has-contrast-background-color {
	--wp--preset--color--contrast:   #111111;
	--wp--preset--color--contrast-2: rgba(255,255,255,0.60);
	--wp--preset--color--contrast-3: rgba(255,255,255,0.35);
	--wp--preset--color--base:       #f5f4f2;
	--wp--preset--color--base-2:     rgba(255,255,255,0.07);
	--wp--preset--color--base-3:     rgba(255,255,255,0.14);
	background-color: #111111 !important;
	color: #f5f4f2;
}

/* Footer template part — always dark regardless of color scheme */
[data-color-scheme="dark"] .wp-site-blocks > .wp-block-template-part:last-child > footer {
	--wp--preset--color--contrast:   #111111;
	--wp--preset--color--contrast-2: rgba(255,255,255,0.55);
	--wp--preset--color--contrast-3: rgba(255,255,255,0.35);
	--wp--preset--color--base:       #f5f4f2;
	--wp--preset--color--base-2:     rgba(255,255,255,0.05);
	--wp--preset--color--base-3:     rgba(255,255,255,0.12);
}
[data-color-scheme="dark"] .wp-site-blocks > .wp-block-template-part:last-child > footer,
[data-color-scheme="dark"] .wp-site-blocks > .wp-block-template-part:last-child > footer .has-contrast-background-color {
	background-color: #111111 !important;
}

/* Accent (navy) background sections — already dark, keep as-is */
[data-color-scheme="dark"] .alignfull.has-accent-background-color {
	background-color: var(--wp--preset--color--accent, #EFC940) !important;
}

/* Dark page hero covers stay dark — overlay already has opacity, no flip needed */
[data-color-scheme="dark"] .wp-block-cover.is-dark {
	/* Cover background is a coloured overlay via opacity, not a preset colour token.
	   No CSS variable override needed — it stays dark automatically. */
}

/* ==========================================================================
   Archive grid cards
   Used on all post/CPT archive pages via .pw-archive-card class.
   The card wrapper is .is-style-plinthworks-card + .pw-archive-card.
   ========================================================================== */

.pw-archive-card {
	height: 100%;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	transition:
		transform   0.3s cubic-bezier(0.16, 1, 0.3, 1),
		box-shadow  0.3s ease;
}

.pw-archive-card:hover {
	transform: translateY(-6px);
}

/* Featured image — fixed 16:9 aspect ratio with placeholder gradient fallback */
.pw-archive-card .wp-block-post-featured-image {
	flex-shrink: 0;
	position: relative;
	overflow: hidden;
	background: linear-gradient(
		135deg,
		var(--wp--preset--color--accent, #EFC940)  0%,
		var(--wp--preset--color--base-2, #F9F7F6)  100%
	);
}

.pw-archive-card .wp-block-post-featured-image a,
.pw-archive-card .wp-block-post-featured-image figure {
	display: block;
}

.pw-archive-card .wp-block-post-featured-image img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
	transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}

.pw-archive-card:hover .wp-block-post-featured-image img {
	transform: scale(1.06);
}

/* Empty featured image slot — show placeholder with fixed height */
.pw-archive-card .wp-block-post-featured-image:not(:has(img)) {
	aspect-ratio: 16 / 9;
}

/* Placeholder for a post with no featured image. Core renders NOTHING at all in
   that case, so the rule above can never match — the element does not exist.
   inc/featured-image-fallback.php supplies this element instead, keeping every
   card the same shape whether or not an editor remembered to set a photo. */
.pw-archive-card .pw-featured-fallback {
	display: block;
	aspect-ratio: 16 / 9;
	position: relative;
	overflow: hidden;
	background:
		radial-gradient(circle at 78% 18%, color-mix(in srgb, var(--wp--preset--color--accent-2, #E9BA13) 55%, transparent) 0%, transparent 55%),
		linear-gradient(135deg,
			var(--wp--preset--color--accent, #EFC940) 0%,
			var(--wp--preset--color--accent-3, #F36F8F) 100%);
}

/* A quiet monogram so the placeholder reads as intentional, not as a failure. */
.pw-archive-card .pw-featured-fallback::after {
	content:     attr(data-initial);
	position:    absolute;
	inset:       0;
	display:     flex;
	align-items: center;
	justify-content: center;
	font-family: var(--wp--preset--font-family--lora, inherit);
	font-size:   clamp(2rem, 5vw, 3.25rem);
	font-weight: 700;
	color:       color-mix(in srgb, var(--wp--preset--color--base, #fff) 82%, transparent);
	letter-spacing: 0.04em;
}

/* Hero cover with useFeaturedImage but no thumbnail set. Core still renders the
   cover, just with no picture behind the dim gradient, so the hero reads as a
   near-black slab. inc/featured-image-fallback.php tags it and we paint the
   brand behind the existing overlay: the hero keeps its height, its layout and
   a readable title, and looks deliberate rather than broken. */
.wp-block-cover.pw-hero-fallback {
	background:
		radial-gradient(circle at 82% 12%, color-mix(in srgb, var(--wp--preset--color--accent-2, #E9BA13) 60%, transparent) 0%, transparent 58%),
		linear-gradient(135deg,
			var(--wp--preset--color--accent, #EFC940) 0%,
			var(--wp--preset--color--accent-3, #F36F8F) 100%);
}

/* The overlay exists to hold text off a photograph. With no photograph it is
   just mud over the brand, so lighten it — the title still clears contrast
   against the gradient beneath. */
.wp-block-cover.pw-hero-fallback > .wp-block-cover__background {
	opacity: 0.42;
}

/* ── "Read more" (core/read-more) ────────────────────────────────────────────
   This was a core/button, which has no way to know the post URL inside a query
   loop, so it rendered an <a> with no href and went nowhere. core/read-more
   links to the post by design; these rules give it the ghost-pill look the
   button had. */
.pw-archive-card .pw-card-more,
.wp-block-post-template .pw-card-more {
	display: inline-block;
	padding: 6px 14px;
	border: 1.5px solid transparent;
	border-radius: 999px;
	background-color: transparent;
	color: var(--wp--preset--color--surface-deep, #343877);
	font-weight: 600;
	text-decoration: none;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.pw-archive-card .pw-card-more:hover,
.wp-block-post-template .pw-card-more:hover {
	background-color: color-mix(in srgb, var(--wp--preset--color--accent, #EFC940) 12%, transparent);
	color: var(--wp--preset--color--surface-deep, #343877);
	text-decoration: none;
}

/* Terms / category chip */
.pw-archive-card .wp-block-post-terms,
.pw-archive-card .wp-block-post-terms a {
	color: var(--wp--preset--color--contrast-3) !important;
	text-decoration: none;
	transition: opacity 0.15s ease;
}

/* Post title link */
.pw-archive-card .wp-block-post-title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	transition: color 0.2s ease;
}

.pw-archive-card .wp-block-post-title a:hover {
	color: var(--wp--preset--color--surface-deep);
}

/* Card body pushes meta footer to the bottom */
.pw-archive-card > .wp-block-group:last-child {
	flex: 1;
	display: flex;
	flex-direction: column;
}

/* Meta/footer row auto-margin pushes it to card bottom */
.pw-archive-card .pw-card-meta {
	margin-top: auto;
	padding-top: var(--wp--preset--spacing--40, 1rem);
	border-top: 1px solid var(--wp--preset--color--base-3, #C8C8C8);
}

/* Team member cards — square portrait */
.pw-archive-card.pw-card-person .wp-block-post-featured-image img {
	aspect-ratio: 1;
}

/* ==========================================================================
   Decorative colour strip utilities
   Add pw-strip-* as className on group blocks for section visual interest.
   ========================================================================== */

.pw-strip-gradient-top {
	position: relative;
}

.pw-strip-gradient-top::before {
	content: '';
	position: absolute;
	top: 0; left: 0; right: 0;
	height: 4px;
	background: linear-gradient(
		90deg,
		var(--wp--preset--color--accent)   0%,
		var(--wp--preset--color--accent-2) 50%,
		var(--wp--preset--color--accent-3) 100%
	);
	z-index: 1;
}

.pw-strip-accent-top   { border-top: 4px solid var(--wp--preset--color--accent)   !important; }
.pw-strip-accent-2-top { border-top: 4px solid var(--wp--preset--color--accent-2) !important; }
.pw-strip-accent-3-top { border-top: 4px solid var(--wp--preset--color--accent-3) !important; }

/* Coloured left-border strip variant */
.pw-strip-accent-left   { border-left: 4px solid var(--wp--preset--color--accent)   !important; }
.pw-strip-accent-2-left { border-left: 4px solid var(--wp--preset--color--accent-2) !important; }

/* ==========================================================================
   Icon system — Lucide SVG icons
   Render via: <i data-lucide="icon-name" class="pw-icon-md"></i>
   Requires: assets/js/lucide.min.js (download once from unpkg.com/lucide)
   1500+ free MIT-licensed icons with CSS animation classes.
   ========================================================================== */

[data-lucide] {
	display: inline-block;
	vertical-align: middle;
	width: 1.25em;
	height: 1.25em;
	stroke: currentColor;
	stroke-width: 1.75;
	stroke-linecap: round;
	stroke-linejoin: round;
	fill: none;
	transition: transform 0.2s ease, opacity 0.2s ease;
}

.pw-icon-xs  { width: 0.875rem; height: 0.875rem; }
.pw-icon-sm  { width: 1rem;     height: 1rem; }
.pw-icon-md  { width: 1.5rem;   height: 1.5rem; }
.pw-icon-lg  { width: 2rem;     height: 2rem; }
.pw-icon-xl  { width: 3rem;     height: 3rem; }
.pw-icon-2xl { width: 4rem;     height: 4rem; }

/* Colour variants */
.pw-icon-accent   { color: var(--wp--preset--color--accent); }
.pw-icon-accent-2 { color: var(--wp--preset--color--accent-2); }
.pw-icon-muted    { color: var(--wp--preset--color--contrast-3); }

/* Animation keyframes */
@keyframes pw-icon-spin   { to { transform: rotate(360deg); } }
@keyframes pw-icon-bounce { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-5px)} }
@keyframes pw-icon-pulse  { 0%,100%{opacity:1} 50%{opacity:0.4} }
@keyframes pw-icon-wiggle { 0%,100%{transform:rotate(0)} 25%{transform:rotate(-12deg)} 75%{transform:rotate(12deg)} }
@keyframes pw-icon-draw   { from{stroke-dashoffset:200} to{stroke-dashoffset:0} }

.pw-icon-spin   { animation: pw-icon-spin   1.4s linear infinite; }
.pw-icon-bounce { animation: pw-icon-bounce 1s ease-in-out infinite; }
.pw-icon-pulse  { animation: pw-icon-pulse  2s ease-in-out infinite; }
.pw-icon-wiggle { animation: pw-icon-wiggle 0.5s ease-in-out infinite; }

.pw-icon-draw [data-lucide],
[data-lucide].pw-icon-draw {
	stroke-dasharray: 200;
	animation: pw-icon-draw 0.8s ease forwards;
}

/* Hover-triggered animation on parent */
.pw-icon-hover:hover [data-lucide] { transform: scale(1.18); }
.pw-icon-hover-spin:hover [data-lucide] { animation: pw-icon-spin 0.6s linear; }

/* ==========================================================================
   Footer — always-dark, matches mega-nav dark palette.
   Layout: 3 columns (brand wider) + newsletter row + bottom bar with social.
   Hovers: animated sliding underline on link lists, lift+scale on social,
   colour-shift only on contact rows (no layout shift).
   ========================================================================== */

.pw-footer {
	/* Local palette override — beats global light/dark scheme inside this scope.
	   The --pw-fdark-* tokens are DERIVED from the site's brand palette by
	   inc/dark-mode.php, so the always-dark footer matches whatever brand the
	   theme is deployed with. The hexes below are only fallbacks. */
	--wp--preset--color--base:       var(--pw-fdark-base, #111827);
	--wp--preset--color--base-2:     var(--pw-fdark-base-2, #1f2937);
	--wp--preset--color--base-3:     var(--pw-fdark-base-3, #374151);
	--wp--preset--color--contrast:   var(--pw-fdark-contrast, #f1f5f9);
	--wp--preset--color--contrast-2: rgba(255, 255, 255, 0.68);
	--wp--preset--color--contrast-3: rgba(255, 255, 255, 0.45);
	--wp--preset--color--accent:     var(--pw-fdark-accent, #5b9bd5);

	background-color: var(--pw-fdark-base, #111827) !important;
	color:            var(--pw-fdark-contrast, #f1f5f9);
	padding-top:      var(--wp--preset--spacing--70, 5rem);
	padding-bottom:   var(--wp--preset--spacing--50, 2rem);
	position:         relative;
	overflow:         hidden;
}

/* Subtle top accent stripe — same accent colour as the mega-nav line */
.pw-footer::before {
	content:    '';
	position:   absolute;
	top:        0;
	left:       0;
	right:      0;
	height:     3px;
	background: linear-gradient(
		90deg,
		var(--wp--preset--color--accent, #EFC940)   0%,
		var(--wp--preset--color--accent-2, #E9BA13) 50%,
		var(--wp--preset--color--accent-3, #F36F8F) 100%
	);
	opacity: 0.85;
}

/* Centre every direct child (EXCEPT dividers) to the same width as the body
   content-size, matching where the newsletter "Stay updated…Subscribe" row
   sits. Dividers stay full-width (see .pw-footer__divider below). */
.pw-footer > .wp-block-columns,
.pw-footer > .wp-block-group {
	max-width:    var( --wp--style--global--content-size, 720px );
	margin-left:  auto;
	margin-right: auto;
}

/* Site title in the footer */
.pw-footer .wp-block-site-title,
.pw-footer .wp-block-site-title a {
	color: #ffffff !important;
}
.pw-footer .wp-block-site-title a:hover {
	color: var(--wp--preset--color--accent, #EFC940) !important;
}

/* Tagline */
.pw-footer__tagline {
	margin:      0.75rem 0 1.5rem;
	font-size:   0.92rem;
	line-height: 1.6;
	color:       rgba(255, 255, 255, 0.7);
}

/* Contact list */
.pw-footer__contact {
	list-style: none;
	margin:     0;
	padding:    0;
	display:    flex;
	flex-direction: column;
	gap:        0.45rem;
	font-size:  0.875rem;
}
.pw-footer__contact li {
	color: rgba(255, 255, 255, 0.78);
}
.pw-footer__contact a {
	position:        relative;
	color:           #f1f5f9;
	text-decoration: none;
	transition:      color 0.18s ease;
}
.pw-footer__contact a::after {
	content:         '';
	position:        absolute;
	left:            0;
	right:           0;
	bottom:          -2px;
	height:          1px;
	background:      currentColor;
	transform:       scaleX(0);
	transform-origin: left center;
	transition:      transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.pw-footer__contact a:hover,
.pw-footer__contact a:focus-visible {
	color:   #ffffff;
	outline: none;
}
.pw-footer__contact a:hover::after,
.pw-footer__contact a:focus-visible::after {
	transform: scaleX(1);
}
.pw-footer__contact-label {
	display:        inline-block;
	min-width:      4.5rem;
	font-size:      0.7rem;
	font-weight:    700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color:          rgba(255, 255, 255, 0.4);
	margin-right:   0.5rem;
}

/* Column heading */
.pw-footer .pw-footer__heading,
.pw-footer h4.pw-footer__heading {
	font-size:      0.78rem;
	font-weight:    700;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color:          rgba(255, 255, 255, 0.55);
	margin:         0 0 1rem;
	padding-bottom: 0.6rem;
	border-bottom:  1px solid rgba(255, 255, 255, 0.08);
}

/* Link lists — sliding underline on hover, no layout shift */
.pw-footer__list {
	list-style: none;
	margin:     0;
	padding:    0;
	display:    flex;
	flex-direction: column;
	gap:        0.6rem;
}
.pw-footer__list a {
	position:        relative;
	display:         inline-block;
	font-size:       0.9rem;
	line-height:     1.4;
	color:           rgba(255, 255, 255, 0.72);
	text-decoration: none;
	transition:      color 0.2s ease;
}
.pw-footer__list a::after {
	content:         '';
	position:        absolute;
	left:            0;
	right:           0;
	bottom:          -3px;
	height:          1px;
	background:      currentColor;
	transform:       scaleX(0);
	transform-origin: left center;
	transition:      transform 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}
.pw-footer__list a:hover,
.pw-footer__list a:focus-visible {
	color:   #ffffff;
	outline: none;
}
.pw-footer__list a:hover::after,
.pw-footer__list a:focus-visible::after {
	transform: scaleX(1);
}

/* Social icons — lift + scale on hover; sit in the bottom bar by default. */
.pw-footer .pw-footer__social.wp-block-social-links {
	margin:    0;
	flex-wrap: wrap;
}
.pw-footer .wp-block-social-link {
	transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1),
	            box-shadow 0.22s ease;
}
.pw-footer .wp-block-social-link:hover {
	transform:  translateY(-3px) scale(1.08);
	box-shadow: 0 6px 14px -4px rgba(0, 0, 0, 0.4);
}

/* Divider — full-width hairline at all viewport sizes. Negative left/right
   margins cancel the footer's horizontal padding so the line truly spans
   edge to edge of the dark band. */
.pw-footer > .pw-footer__divider.wp-block-separator {
	max-width:     none;
	width:         auto;
	border:        none;
	height:        1px;
	background:    rgba(255, 255, 255, 0.18);
	opacity:       1;
	margin-top:    var(--wp--preset--spacing--60, 3rem);
	margin-bottom: var(--wp--preset--spacing--50, 2rem);
	margin-left:   calc( -1 * var(--wp--preset--spacing--60, 3rem) );
	margin-right:  calc( -1 * var(--wp--preset--spacing--60, 3rem) );
}

/* Newsletter row — full-width strip below the three columns. */
.pw-footer__newsletter-row {
	padding: 0.5rem 0;
}

/* Bottom bar — copyright | legal | social, evenly spaced and aligned. */
.pw-footer__bottom {
	display:         flex;
	flex-wrap:       wrap;
	gap:             1.5rem;
	align-items:     center;
	justify-content: space-between;
	font-size:       0.82rem;
	color:           rgba(255, 255, 255, 0.5);
}
.pw-footer__bottom > * {
	margin: 0;
}
.pw-footer__copyright {
	flex: 0 0 auto;
	margin: 0;
}
.pw-footer__legal {
	list-style:      none;
	margin:          0;
	padding:         0;
	display:         flex;
	gap:             1.5rem;
	flex-wrap:       wrap;
	flex:            1 1 auto;
	justify-content: center;
}
.pw-footer__legal li {
	margin: 0;
}
.pw-footer__legal a {
	position:        relative;
	color:           rgba(255, 255, 255, 0.55);
	text-decoration: none;
	transition:      color 0.18s ease;
}
.pw-footer__legal a::after {
	content:         '';
	position:        absolute;
	left:            0;
	right:           0;
	bottom:          -3px;
	height:          1px;
	background:      currentColor;
	transform:       scaleX(0);
	transform-origin: left center;
	transition:      transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.pw-footer__legal a:hover,
.pw-footer__legal a:focus-visible {
	color:   #ffffff;
	outline: none;
}
.pw-footer__legal a:hover::after,
.pw-footer__legal a:focus-visible::after {
	transform: scaleX(1);
}

/* Newsletter inside the footer — accent palette stays consistent */
.pw-footer .pw-newsletter {
	margin: 0;
}
.pw-footer .pw-newsletter__heading {
	color:          #ffffff;
	font-size:      1.35rem;
	font-weight:    700;
	letter-spacing: -0.01em;
	text-transform: none;
	margin-bottom:  0;
	padding-bottom: 0;
	border-bottom:  none;
}
.pw-footer .pw-newsletter__subheading {
	color:   rgba(255, 255, 255, 0.65);
	margin:  0;
	opacity: 1;
	font-size: 0.92rem;
}
.pw-footer .pw-newsletter__input {
	/* shorthand: top   horizontal   bottom — extra ~0.15rem on top so the
	   placeholder/text sits visually centred regardless of line-height. */
	padding:      clamp( 0.75rem, 1.9vw, 1rem ) clamp( 0.8rem, 2vw, 1.1rem ) clamp( 0.55rem, 1.5vw, 0.8rem );
	font-size:    clamp( 0.82rem, 1.9vw, 0.95rem );
	background:   rgba(255, 255, 255, 0.05);
	border-color: rgba(255, 255, 255, 0.14);
	color:        #f1f5f9;
}
.pw-footer .pw-newsletter__input:focus {
	background:   rgba(255, 255, 255, 0.10);
	border-color: rgba(91, 155, 213, 0.6);
	box-shadow:   0 0 0 3px rgba(91, 155, 213, 0.18);
}
.pw-footer .pw-newsletter__btn {
	padding:    clamp( 0.6rem, 1.6vw, 0.85rem ) clamp( 1.05rem, 2.6vw, 1.7rem );
	font-size:  clamp( 0.74rem, 1.7vw, 0.85rem );
	background: var(--wp--preset--color--accent, #EFC940);
	color:      #ffffff;
}
.pw-footer .pw-newsletter__btn:hover {
	background: #4a8dc5;
	transform:  translateY(-2px);
	box-shadow: 0 8px 18px -4px rgba(91, 155, 213, 0.45);
}

/* Responsive: on mobile show only the brand column, newsletter, and bottom
   bar (year + legal + social). All visible content is centre-aligned. */
@media (max-width: 781px) {
	.pw-footer .wp-block-columns {
		flex-direction: column !important;
		gap:            var(--wp--preset--spacing--50, 2rem);
	}
	.pw-footer .wp-block-column {
		flex-basis: 100% !important;
		width:      100% !important;
	}
	.pw-footer > .wp-block-columns > .wp-block-column:not(:first-child) {
		display: none !important;
	}

	/* Centre everything visible on mobile. */
	.pw-footer > .wp-block-columns > .wp-block-column:first-child,
	.pw-footer > .wp-block-columns > .wp-block-column:first-child .wp-block-site-title,
	.pw-footer__newsletter-row,
	.pw-footer__bottom {
		text-align: center;
	}

	/* Brand contact list */
	.pw-footer__contact {
		align-items: center;
	}
	.pw-footer__contact li {
		text-align: center;
	}

	/* Newsletter — heading/subheading + form all centre */
	.pw-footer .pw-newsletter {
		align-items: center;
	}
	.pw-footer .pw-newsletter__heading,
	.pw-footer .pw-newsletter__subheading {
		text-align: center;
	}
	.pw-footer .pw-newsletter__form {
		justify-content: center;
	}

	/* Bottom bar — stack centred (copyright above legal above social) */
	.pw-footer__bottom {
		justify-content: center;
		flex-direction:  column;
		align-items:     center;
		gap:             1rem;
	}
	.pw-footer__legal {
		justify-content: center;
	}
	.pw-footer .pw-footer__social.wp-block-social-links {
		justify-content: center;
	}

	/* Tighter newsletter spacing on mobile (input + button size already
	   scaled fluidly with clamp() above). */
	.pw-footer .pw-newsletter {
		gap: 0.5rem;
	}
	.pw-footer .pw-newsletter__heading {
		font-size:     1.1rem;
		margin-bottom: 0;
	}
	.pw-footer .pw-newsletter__subheading {
		font-size:   0.85rem;
		line-height: 1.5;
	}
	.pw-footer__newsletter-row {
		padding: 0;
	}

	/* Mobile-only: tighten the vertical breathing room of the dividers
	   (full-width treatment is shared with desktop in the base rule above). */
	.pw-footer > .pw-footer__divider.wp-block-separator {
		margin-top:    var(--wp--preset--spacing--40, 1rem);
		margin-bottom: var(--wp--preset--spacing--40, 1rem);
	}
	/* The divider immediately after the newsletter row gets even less top
	   padding — the newsletter form already has enough breathing room below. */
	.pw-footer > .pw-footer__newsletter-row + .pw-footer__divider.wp-block-separator {
		margin-top: 0.35rem;
	}
}

/* ──────────────────────────────────────────────────────────────────────────
   "Full width" block style (core/group, core/columns, core/cover)
   One-click full-bleed for any section, even nested inside a constrained
   container (native Full-width alignment only breaks out of the nearest
   constrained parent). Standard page content keeps its comfortable indentation;
   only the toggled element spans edge to edge — ideal for CTAs, covers, sliders.
   ────────────────────────────────────────────────────────────────────────── */
.wp-block-group.is-style-plinthworks-full-width,
.wp-block-columns.is-style-plinthworks-full-width,
.wp-block-cover.is-style-plinthworks-full-width {
	max-width: none;
	margin-left: calc(-1 * var(--wp--style--root--padding-left, 0px));
	margin-right: calc(-1 * var(--wp--style--root--padding-right, 0px));
}
/* Keep the section's inner content comfortably indented while the background
   spans edge to edge. (A layout:constrained group already does this for its
   children; this is the belt-and-braces fallback for plain-flow groups.) */
.is-style-plinthworks-full-width.is-layout-flow > :where(:not(.alignfull):not(.alignwide)) {
	max-width: var(--wp--style--global--content-size, 1100px);
	margin-left: auto;
	margin-right: auto;
	padding-left: var(--wp--style--root--padding-left, 1.5rem);
	padding-right: var(--wp--style--root--padding-right, 1.5rem);
}

/* ──────────────────────────────────────────────────────────────────────────
   Block style: Card Hover (core/group, core/columns, core/column)
   is-style-plinthworks-card-hover — a card with its own resting + hover colours
   that lifts on hover, recolours EVERY element inside (icons, headings, text…),
   and can become a whole-card link. Colours are set per block in the editor
   (Card Hover panel) and arrive as --pw-card-bg / --pw-card-text /
   --pw-card-hover-bg / --pw-card-hover-text; the stretched <a> is injected
   server-side (inc/card-hover.php).

   :is() widens the host block without duplicating any rule. Every argument is
   a single class, so specificity is unchanged from the original selector.
   ────────────────────────────────────────────────────────────────────────── */
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-hover {
	position: relative;
	background-color: var( --pw-card-bg, var( --wp--preset--color--base, #fff ) );
	color: var( --pw-card-text, inherit );
	border: 1px solid var(--wp--preset--color--base-3, #C8C8C8);
	border-radius: var(--wp--custom--radius--large, 16px);
	overflow: hidden;
	transition: background-color 0.28s ease, color 0.28s ease, transform 0.28s ease,
		box-shadow 0.28s ease, border-color 0.28s ease;
}
/* When a resting Text colour is chosen, apply it to every element inside
   (icons recolour via currentColor). The .pw-card-has-text class is added by
   inc/card-hover.php; it replaced a [style*="--pw-card-text"] substring match,
   which was brittle — it also matched --pw-card-hover-text, so choosing only a
   HOVER text colour wrongly recoloured the card at rest. */
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-hover.pw-card-has-text :where(h1,h2,h3,h4,h5,h6,p,li,a,.wp-block-heading,.wp-block-post-title,svg) {
	color: var( --pw-card-text );
}
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-hover:hover {
	background-color: var( --pw-card-hover-bg, var( --wp--preset--color--accent, #EFC940 ) );
	transform: translateY(-6px);
	box-shadow: 0 16px 34px -14px rgba(17, 24, 39, 0.3);
	border-color: transparent;
}
/* On hover recolour the card AND every element inside it (icons via
   currentColor, headings, paragraphs, lists, links) so content stays readable
   on the new background. */
/* Buttons are excluded: they carry their own background, so forcing the card's
   hover text colour onto them produced white-on-light (or worse) and was the
   most visible part of the "inversion" problem. They keep their own contrast. */
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-hover:hover,
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-hover:hover
	*:not(.pw-card-hover__link):not(.wp-element-button):not(.wp-block-button__link):not(.wp-block-button):not(.wp-block-buttons) {
	color: var( --pw-card-hover-text, #ffffff );
}
/* Soften an icon badge's fill so it reads on the hover colour. */
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-hover:hover .mhm-feature-icon {
	background: rgba(255, 255, 255, 0.16);
}

/* Stretched link — makes the whole card clickable and keyboard-focusable. */
.pw-card-hover__link {
	position: absolute;
	inset: 0;
	z-index: 1;
	font-size: 0;
	color: transparent;
	border-radius: inherit;
}
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-hover:has( .pw-card-hover__link ) { cursor: pointer; }
.pw-card-hover__link:focus-visible {
	outline: 3px solid var( --wp--preset--color--surface-deep, #343877 );
	outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
	:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-hover:hover { transform: none; }
}

/* ==========================================================================
   Adaptive media scrim — applied by assets/js/dark-mode.js after measuring
   the actual pixels of a cover's photo. The alpha is computed to be the
   smallest veil that brings the existing text to a readable ratio, so a
   photo that is already legible never gets one.
   ========================================================================== */

.pw-media-scrim { position: relative; }
.pw-media-scrim::after {
	content:        '';
	position:       absolute;
	inset:          0;
	background:     var(--pw-media-scrim, transparent);
	pointer-events: none;
	z-index:        1;
	transition:     background 0.35s ease;
}
.pw-media-scrim > .wp-block-cover__inner-container,
.pw-media-scrim > * { position: relative; z-index: 2; }

/* Media layers sit behind the scrim, and must keep the positioning their own
   block gave them. The blanket `> *` rule above lifts every direct child to
   `position: relative` so it can take a z-index — which silently breaks any
   child that was absolutely positioned to fill its parent: `inset: 0` stops
   resolving against the parent box, the element collapses to zero height, and
   a slide background disappears while its markup, its URL and its
   background-image all still look perfectly correct in DevTools.
   Restoring `position` alongside `z-index` is the whole fix. */
.pw-media-scrim > img,
.pw-media-scrim > .wp-block-cover__background,
.pw-media-scrim > .pw-slide-bg,
.pw-media-scrim > video { z-index: 0; }

.pw-media-scrim > .wp-block-cover__background,
.pw-media-scrim > .pw-slide-bg { position: absolute; }

/* Adaptive ink over media: when a cover's text colour was inherited rather
   than chosen, the script picks the ink that suits the photograph so the
   image keeps its brightness instead of being veiled. :where() keeps this at
   zero specificity, so any explicit colour the author sets still wins. */
.pw-media-ink :where(h1,h2,h3,h4,h5,h6,p,blockquote,cite,li,figcaption) {
	color: var(--pw-media-ink, inherit);
}

/* Forced ink: used only when honouring the author's text colour would require
   a veil heavy enough to destroy the photograph. Higher specificity + !important
   so it beats WordPress's preset colour classes, which also use !important. */
.pw-media-ink--force h1,
.pw-media-ink--force h2,
.pw-media-ink--force h3,
.pw-media-ink--force h4,
.pw-media-ink--force h5,
.pw-media-ink--force h6,
.pw-media-ink--force p,
.pw-media-ink--force li,
.pw-media-ink--force blockquote,
.pw-media-ink--force cite,
.pw-media-ink--force figcaption,
.pw-media-ink--force span:not([class*="button"]) {
	color: var(--pw-media-ink) !important;
}

/* ==========================================================================
   Rich card treatments — lift, gradient border, spotlight, image reveal
   Apply as a block style on any Group. Self-contained (own surface + padding).
   Lift is also available on Columns and Column (see inc/block-styles.php).
   ========================================================================== */

:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-lift,
.wp-block-group.is-style-plinthworks-card-image-reveal {
	position: relative;
	background: var(--pw-surface, var(--wp--preset--color--base, #fff));
	border-radius: var(--wp--custom--radius--large, 16px);
	padding: clamp(1.5rem, 3vw, 2.25rem);
	transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Lift — rises with a soft shadow */
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-lift {
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(0, 0, 0, 0.04);
}
:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-lift:hover {
	transform: translateY(-8px);
	box-shadow: 0 28px 70px -22px rgba(0, 0, 0, 0.28);
}

/* Image reveal — an image child zooms + saturates on hover */
.wp-block-group.is-style-plinthworks-card-image-reveal {
	overflow: hidden;
	padding: 0;
}
.wp-block-group.is-style-plinthworks-card-image-reveal .wp-block-image {
	overflow: hidden;
	margin: 0;
}
.wp-block-group.is-style-plinthworks-card-image-reveal .wp-block-image img {
	display: block;
	width: 100%;
	transition: transform 0.7s cubic-bezier(0.16, 1, 0.3, 1), filter 0.5s ease;
	will-change: transform;
}
.wp-block-group.is-style-plinthworks-card-image-reveal:hover .wp-block-image img {
	transform: scale(1.08);
	filter: saturate(1.08);
}
.wp-block-group.is-style-plinthworks-card-image-reveal:hover {
	box-shadow: 0 28px 70px -22px rgba(0, 0, 0, 0.28);
}

@media (prefers-reduced-motion: reduce) {
	:is(.wp-block-group, .wp-block-columns, .wp-block-column).is-style-plinthworks-card-lift:hover { transform: none; }
	.wp-block-group.is-style-plinthworks-card-image-reveal:hover .wp-block-image img { transform: none; }
}

/* ==========================================================================
   Flip card — hover swaps the front face for the back (hover interchangeability)
   Structure: .pw-flip > .pw-flip__inner > .pw-flip__front + .pw-flip__back
   ========================================================================== */
.pw-flip { perspective: 1400px; }
.pw-flip__inner {
	position: relative;
	transition: transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
	transform-style: preserve-3d;
	min-height: var(--pw-flip-h, 240px);
}
.pw-flip:hover .pw-flip__inner,
.pw-flip:focus-within .pw-flip__inner { transform: rotateY(180deg); }
.pw-flip__front,
.pw-flip__back {
	position: absolute;
	inset: 0;
	-webkit-backface-visibility: hidden;
	        backface-visibility: hidden;
	border-radius: var(--wp--custom--radius--large, 16px);
	padding: clamp(1.25rem, 3vw, 2rem);
	display: flex;
	flex-direction: column;
	justify-content: center;
	overflow: hidden;
}
.pw-flip__front { background: var(--pw-surface, var(--wp--preset--color--base, #fff)); box-shadow: 0 1px 3px rgba(0,0,0,.06), 0 0 0 1px rgba(0,0,0,.04); }
.pw-flip__back  { transform: rotateY(180deg); background: var(--wp--preset--color--accent, #EFC940); color: var(--wp--preset--color--on-action, #333); }
.pw-flip__back :where(h1,h2,h3,h4,h5,h6,p,a) { color: inherit; }
@media (prefers-reduced-motion: reduce) {
	.pw-flip__inner { transition: none; }
	/* Reduced motion: show the back stacked below instead of a 3D flip */
	.pw-flip:hover .pw-flip__inner { transform: none; }
	.pw-flip__back { position: static; transform: none; margin-top: 8px; }
	.pw-flip__front, .pw-flip__back { backface-visibility: visible; }
}

/* ==========================================================================
   Button icons (front end) — spacing, sizing, arrow-nudge on hover
   ========================================================================== */
.pw-btn-icon { display: inline-flex; align-items: center; vertical-align: middle; line-height: 0; }

/*
 * Two selectors, because the icon arrives in two shapes.
 *
 * inc/icons.php replaces <i data-lucide="…" class="pw-btn-icon"> with an <svg>
 * and CARRIES THE CLASS ONTO THE SVG ITSELF. So on the front end the element is
 * `svg.pw-btn-icon`, not an svg inside `.pw-btn-icon`. Only the descendant form
 * was styled, so the rule never matched and the icon fell back to its own
 * width="24" attribute — rendering at 24px instead of ~16.6px. That is why
 * icons looked oversized next to the label, and why the button's padding
 * compensation under-shot by exactly the difference.
 */
.pw-btn-icon svg,
svg.pw-btn-icon {
	width:  var(--wp--custom--button--icon-size, 1.05em);
	height: var(--wp--custom--button--icon-size, 1.05em);
	flex-shrink: 0;
}
.pw-btn-icon--before { margin-right: var(--wp--custom--button--icon-gap, 0.55em); transition: transform 0.25s ease; }
.pw-btn-icon--after  { margin-left:  var(--wp--custom--button--icon-gap, 0.55em); transition: transform 0.25s ease; }

/*
 * Keep an icon button exactly as wide as one without an icon.
 *
 * The icon is real inline content, so it adds its own width plus the gap. Half
 * of that total is reclaimed from each side's padding, leaving the outer size
 * unchanged with the icon and label still optically centred.
 *
 * Every number comes from theme.json (custom.button.paddingX / iconSize /
 * iconGap) and the same tokens size the icon itself above, so the compensation
 * cannot drift from the icon's real footprint. Measured in Chrome: a button with
 * an icon is within 0.05px of one without, at 360/768/1280/1600.
 *
 * max() is a floor — if the padding is ever set smaller than the icon needs,
 * the button stops shrinking rather than collapsing onto its label.
 */
.wp-block-button__link.pw-btn-has-icon,
.wp-element-button.pw-btn-has-icon {
	padding-inline: max(
		0.6em,
		calc(
			var(--wp--custom--button--padding-x, 1.5rem)
			- ( ( var(--wp--custom--button--icon-size, 1.05em) + var(--wp--custom--button--icon-gap, 0.55em) ) / 2 )
		)
	);
}
.wp-element-button:hover .pw-btn-icon--after,
.wp-block-button__link:hover .pw-btn-icon--after { transform: translateX(4px); }
.wp-element-button:hover .pw-btn-icon--before,
.wp-block-button__link:hover .pw-btn-icon--before { transform: translateX(-3px); }
/* Icon only — hide the label, keep a compact square target */
.wp-block-button__link.pw-btn-icon-only { font-size: 0; padding-left: 0.7em; padding-right: 0.7em; }
.wp-block-button__link.pw-btn-icon-only .pw-btn-icon { font-size: 1rem; margin: 0; }
/* Same two shapes as above — the class can be on the svg itself. */
.wp-block-button__link.pw-btn-icon-only .pw-btn-icon svg,
.wp-block-button__link.pw-btn-icon-only svg.pw-btn-icon { width: 1.2rem; height: 1.2rem; }

/* ==========================================================================
   Picture reveal (group / columns / column)

   Same idea as Card Hover — drop it on any group or column — except what the
   hover swaps is a picture rather than a colour. The picture is whichever
   core/image sits directly inside the block, so there is nothing to configure
   and no new block to learn: add an image, apply the style.

   The image is lifted out of the flow and pinned over the card, which is what
   lets the card keep the height of its CONTENT. Sizing the card to the image
   instead would make a one-line card as tall as a photograph.

   Reversed swaps which layer rests on top, so "card reveals a picture" and
   "picture reveals a card" are one mechanism used two ways.
   ========================================================================== */

:is(.wp-block-group, .wp-block-columns, .wp-block-column):is(
	.is-style-plinthworks-picture-reveal,
	.is-style-plinthworks-picture-reveal-flip
) {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

/* The picture layer, injected by inc/picture-reveal.php from the block's own
   setting. `> .wp-block-image` is still honoured so anything built against the
   earlier child-image approach keeps working. */
:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > :is(.pw-preveal__img, .wp-block-image),
:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .pw-preveal__tint {
	position: absolute;
	inset: 0;
	z-index: 2;
	margin: 0;
	pointer-events: none;
	border-radius: var(--pw-preveal-radius, 0);
	transition:
		opacity var(--pw-preveal-duration, var(--wp--custom--transition--slow, 320ms)) ease,
		transform var(--pw-preveal-duration, var(--wp--custom--transition--slow, 320ms)) cubic-bezier(0.16, 1, 0.3, 1);
}

:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .pw-preveal__img,
:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .wp-block-image,
:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .wp-block-image img {
	width: 100%;
	height: 100%;
	object-fit: var(--pw-preveal-fit, cover);
	object-position: var(--pw-preveal-pos, 50% 50%);
}

/* The tint rides with the picture, above it. */
:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .pw-preveal__tint {
	z-index: 3;
	background: var(--pw-preveal-tint, transparent);
	opacity: 0;
}

/* Editor canvas: render_block never runs there, so the picture comes in as a
   background image on a pseudo-element instead. */
.pw-preveal--editor::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	border-radius: var(--pw-preveal-radius, 0);
	background-image: var(--pw-preveal-editor-img);
	background-size: var(--pw-preveal-fit, cover);
	background-position: var(--pw-preveal-pos, 50% 50%);
	background-repeat: no-repeat;
	transition: opacity var(--pw-preveal-duration, 320ms) ease;
}

/* Content sits above the picture at rest and is what gives the card its size.

   The exclusion is an attribute match, not a chain of :not() class tests. Every
   layer this feature injects is named pw-preveal__*, and each time one was
   added (tint, overlay, stretched link) it fell through a :not() chain written
   before it existed and got styled as content — the stretched link came out
   position:relative at 0x0, so the whole-card link silently did nothing. */
:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > :not([class*="pw-preveal__"]):not(.wp-block-image) {
	position: relative;
	z-index: 3;
	transition: opacity var(--wp--custom--transition--slow, 320ms) ease;
}

/* ── Resting ─────────────────────────────────────────────────────────────── */

.is-style-plinthworks-picture-reveal > :is(.pw-preveal__img, .wp-block-image) { opacity: 0; transform: scale(var(--pw-preveal-scale, 1.04)); }
.pw-preveal--editor.is-style-plinthworks-picture-reveal::before { opacity: 0; }

.is-style-plinthworks-picture-reveal-flip > :is(.pw-preveal__img, .wp-block-image) { opacity: 1; transform: none; }
/* The tint belongs to the picture, so it is visible exactly when the picture
   is — which on the reversed variant means at rest, not on hover. */
.is-style-plinthworks-picture-reveal-flip > .pw-preveal__tint { opacity: var(--pw-preveal-tint-op, 0); }
.is-style-plinthworks-picture-reveal-flip:is(:hover, :focus-within) > .pw-preveal__tint { opacity: 0; }
.pw-preveal--editor.is-style-plinthworks-picture-reveal-flip::before { opacity: 1; }
.is-style-plinthworks-picture-reveal-flip > :not([class*="pw-preveal__"]):not(.wp-block-image) { opacity: 0; }

/* ── Revealed ────────────────────────────────────────────────────────────────
   focus-within keeps it reachable by keyboard when the card holds a link. */

.is-style-plinthworks-picture-reveal:is(:hover, :focus-within) > :is(.pw-preveal__img, .wp-block-image) {
	opacity: 1;
	transform: none;
}
.is-style-plinthworks-picture-reveal:is(:hover, :focus-within) > .pw-preveal__tint { opacity: var(--pw-preveal-tint-op, 0); }
/* The content clears out so the picture is actually revealed rather than being
   sat on top of. This is the exact mirror of the reversed variant, which is
   what makes the two one mechanism instead of two behaviours.
   Note the consequence: while the picture is showing, the content is not
   clickable. If the card needs a live link under the photo, reverse it. */
.is-style-plinthworks-picture-reveal:is(:hover, :focus-within) > :not([class*="pw-preveal__"]):not(.wp-block-image) { opacity: 0; }

.is-style-plinthworks-picture-reveal-flip:is(:hover, :focus-within) > :is(.pw-preveal__img, .wp-block-image) {
	opacity: 0;
	transform: scale(var(--pw-preveal-scale, 1.04));
}
.is-style-plinthworks-picture-reveal-flip:is(:hover, :focus-within) > :not([class*="pw-preveal__"]):not(.wp-block-image) { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
	:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > :is(.pw-preveal__img, .pw-preveal__tint, .wp-block-image),
	:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > :not([class*="pw-preveal__"]):not(.wp-block-image) {
		transition-duration: 1ms;
	}
	.is-style-plinthworks-picture-reveal > :is(.pw-preveal__img, .wp-block-image),
	.is-style-plinthworks-picture-reveal-flip:is(:hover, :focus-within) > :is(.pw-preveal__img, .wp-block-image) { transform: none; }
}

/* ── Picture reveal: the overlay on the picture ───────────────────────────────
   Icon, title, text and a call to action, sitting on the revealed photograph.

   This is also what makes the normal direction usable at all: the card's own
   content is hidden while the picture shows, so the overlay is the only thing
   left to click. It is therefore the ONE part of the picture layer that takes
   pointer events — everything else stays inert so the hover target is the card.
   ────────────────────────────────────────────────────────────────────────── */

:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .pw-preveal__overlay {
	--pw-preveal-ink: #ffffff;

	position: absolute;
	inset: 0;
	z-index: 6;
	display: flex;
	flex-direction: column;
	gap: var(--pw-preveal-gap, 9px);
	padding: clamp(1rem, 3vw, 1.75rem);
	color: var(--pw-preveal-ink);
	border-radius: var(--pw-preveal-radius, 0);
	pointer-events: none;
	opacity: 0;
	transition: opacity var(--pw-preveal-duration, 320ms) ease;
}

.pw-preveal__overlay.is-align-center { align-items: center; justify-content: center; text-align: center; }
.pw-preveal__overlay.is-align-start  { align-items: flex-start; justify-content: flex-end; text-align: start; }
.pw-preveal__overlay.is-align-end    { align-items: flex-end; justify-content: flex-end; text-align: end; }

.pw-preveal__icon { line-height: 0; }
.pw-preveal__icon svg { width: var(--pw-preveal-icon-size, 28px); height: var(--pw-preveal-icon-size, 28px); }
.pw-preveal__icon--link { color: inherit; text-decoration: none; background-image: none; }
.pw-preveal__icon--link:focus-visible { outline: 3px solid var(--pw-preveal-ink); outline-offset: 3px; }

.pw-preveal__title {
	font-family: var(--wp--preset--font-family--glonto, inherit);
	font-size: var(--pw-preveal-title-size, 22px);
	line-height: 1.08;
	letter-spacing: 0.03em;
	text-transform: uppercase;
}

.pw-preveal__text {
	font-size: var(--pw-preveal-text-size, 15px);
	line-height: 1.45;
	max-width: 34ch;
	opacity: 0.92;
}

/* The call to action reads as a button but is a link, so it keeps link
   semantics for a screen reader and the keyboard. */
.pw-preveal__cta {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	margin-top: 0.25rem;
	padding: 0.65em 1.15em;
	font-size: var(--pw-preveal-cta-size, 14px);
	font-weight: 600;
	line-height: 1;
	color: var(--wp--preset--color--contrast);
	background: var(--wp--preset--color--accent-3);
	text-decoration: none;
	/* The theme's animated content-link underline must not reach in here. */
	background-image: none;
	transition: background-color var(--pw-preveal-duration, 320ms) ease, color var(--pw-preveal-duration, 320ms) ease;
}

.pw-preveal__cta:hover,
.pw-preveal__cta:focus-visible {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--base);
}
.pw-preveal__cta:focus-visible { outline: 3px solid var(--pw-preveal-ink); outline-offset: 2px; }

.pw-preveal__cta-arrow { transition: transform var(--pw-preveal-duration, 320ms) cubic-bezier(0.16, 1, 0.3, 1); }
.pw-preveal__cta:hover .pw-preveal__cta-arrow { transform: translateX(3px); }

/* The overlay appears with the picture, in whichever direction that is, and
   only then becomes clickable. */
.is-style-plinthworks-picture-reveal:is(:hover, :focus-within) > .pw-preveal__overlay,
.is-style-plinthworks-picture-reveal-flip > .pw-preveal__overlay {
	opacity: 1;
}
.is-style-plinthworks-picture-reveal-flip:is(:hover, :focus-within) > .pw-preveal__overlay {
	opacity: 0;
}

/* The overlay box NEVER captures clicks, even when visible — it covers the
   whole card, so making it clickable swallowed the whole-card link entirely.
   Only its actual controls take pointer events, and only once revealed, so a
   hidden link can never be clicked or tabbed into by accident. */
.pw-preveal__cta,
.pw-preveal__icon--link { pointer-events: none; }

.is-style-plinthworks-picture-reveal:is(:hover, :focus-within) :is(.pw-preveal__cta, .pw-preveal__icon--link),
.is-style-plinthworks-picture-reveal-flip :is(.pw-preveal__cta, .pw-preveal__icon--link) {
	pointer-events: auto;
}
.is-style-plinthworks-picture-reveal-flip:is(:hover, :focus-within) :is(.pw-preveal__cta, .pw-preveal__icon--link) {
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
	:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .pw-preveal__overlay,
	.pw-preveal__cta,
	.pw-preveal__cta-arrow { transition-duration: 1ms; }
	.pw-preveal__cta:hover .pw-preveal__cta-arrow { transform: none; }
}

/* Whole-card link. Sits above the picture but BELOW the overlay's own links,
   so a card link and a CTA pointing elsewhere can coexist — the CTA wins where
   they overlap, the card link takes everything else. */
:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .pw-preveal__stretch {
	position: absolute;
	inset: 0;
	z-index: 5;
	border-radius: var(--pw-preveal-radius, 0);
	text-decoration: none;
	background-image: none;
}
:is(.is-style-plinthworks-picture-reveal, .is-style-plinthworks-picture-reveal-flip) > .pw-preveal__stretch:focus-visible {
	outline: 3px solid var(--wp--preset--color--base, #ffffff);
	outline-offset: -3px;
	box-shadow: inset 0 0 0 6px var(--wp--preset--color--surface-deep, #343877);
}

/* The overlay sits above the stretched link (z-index 6 on its own rule), and
   its interactive children above that again. */
.pw-preveal__cta,
.pw-preveal__icon--link { position: relative; z-index: 7; }

/* Not every theme ships this and the stretched link depends on it. */
.pw-preveal__stretch .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}
