/**
 * Article content.
 *
 * Everything an editor writes in Gutenberg lands inside .wpx-prose. Rather
 * than pushing each post into fixed fields — which fights content that
 * genuinely differs post to post — the blocks themselves are styled to match
 * the rest of the theme.
 *
 * Covers: headings, tables, lists, quotes, code, images with captions,
 * buttons, separators, embeds, and the details/summary accordions used for
 * FAQ sections.
 */

/* ==========================================================================
   Rhythm
   ==========================================================================
   Spacing hangs off each block's own bottom margin rather than a
   `> * + *` child rule.

   The child combinator only reaches blocks that sit directly inside
   .wpx-prose. Content imported from another site is often wrapped — in a
   div, a section, a stray container from the old template — and every one
   of those wrappers puts the paragraphs out of reach. Bottom margins work
   at any depth, which is what content of unknown shape needs.
   ========================================================================== */

.wpx-prose {
	color: var(--wpx-text-muted);
	font-size: var(--wpx-text-base);
	line-height: 1.75;
}

.wpx-prose p,
.wpx-prose ul,
.wpx-prose ol,
.wpx-prose dl,
.wpx-prose blockquote,
.wpx-prose pre,
.wpx-prose figure,
.wpx-prose table,
.wpx-prose .wp-block-table,
.wpx-prose .wp-block-image,
.wpx-prose .wp-block-buttons,
.wpx-prose .wp-block-embed,
.wpx-prose details,
.wpx-prose iframe,
.wpx-prose > div {
	margin-block-end: var(--wpx-space-5);
}

/* Running prose sits a little tighter than a block against a figure. */
.wpx-prose p { margin-block-end: var(--wpx-space-4); }

/* An image or table on its own line needs air on both sides. */
.wpx-prose figure,
.wpx-prose .wp-block-image,
.wpx-prose .wp-block-table,
.wpx-prose .wp-block-embed,
.wpx-prose iframe {
	margin-block: var(--wpx-space-5);
}

/* No trailing gap at the end of the article, and none above the first block. */
.wpx-prose > :first-child { margin-block-start: 0; }
.wpx-prose > :last-child { margin-block-end: 0; }

/* A wrapper contributed by imported content should not add a second gap on
   top of the gaps its own children already carry. */
.wpx-prose > div > :last-child { margin-block-end: 0; }

/* Content pasted as plain text separated by line breaks has no paragraphs to
   space. Give the breaks some room so it does not read as one block. */
.wpx-prose br { content: ""; display: block; margin-block-end: var(--wpx-space-2); }

/* ==========================================================================
   Headings
   ========================================================================== */

.wpx-prose h2 {
	position: relative;
	margin-block: var(--wpx-space-7) var(--wpx-space-4);
	padding-inline-start: var(--wpx-space-4);
	font-size: var(--wpx-text-2xl);
	color: var(--wpx-text);
	line-height: 1.25;
}

/* An accent bar rather than an underline: it survives a two-line heading,
   which the underline did not. */
.wpx-prose h2::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	top: 0.18em;
	bottom: 0.18em;
	width: 4px;
	border-radius: var(--wpx-radius-pill);
	background: linear-gradient( 180deg, var(--wpx-accent), var(--wpx-secondary) );
}

.wpx-prose h3 {
	margin-block: var(--wpx-space-6) var(--wpx-space-3);
	font-size: var(--wpx-text-xl);
	color: var(--wpx-text);
}

.wpx-prose h4 {
	margin-block: var(--wpx-space-5) var(--wpx-space-2);
	font-size: var(--wpx-text-lg);
	color: var(--wpx-text);
}

.wpx-prose h2:first-child,
.wpx-prose h3:first-child { margin-block-start: 0; }

/* ==========================================================================
   Text
   ========================================================================== */

/* Deliberately not `.wpx-prose p { margin: 0 }`. That selector carries one
   more element than the rhythm rule above it, so it won every paragraph and
   removed the space between them. Reset the first child instead, and let the
   rhythm rule own the gaps. */


.wpx-prose strong,
.wpx-prose b { color: var(--wpx-text); font-weight: var(--wpx-weight-bold); }

.wpx-prose a {
	color: var(--wpx-accent);
	text-decoration: underline;
	text-decoration-color: rgb(from var(--wpx-accent) r g b / 0.35);
	text-underline-offset: 3px;
	transition: color var(--wpx-transition), text-decoration-color var(--wpx-transition);
}

.wpx-prose a:hover {
	color: var(--wpx-accent-hover);
	text-decoration-color: currentColor;
}

/* A centred link line on its own — the "you may also like" pattern — reads
   as a callout rather than a stray sentence. */
.wpx-prose p.has-text-align-center:has(> a:only-child),
.wpx-prose p[style*="text-align:center"]:has(> a:only-child) {
	padding: var(--wpx-space-4);
	background: var(--wpx-surface-2);
	border: 1px solid var(--wpx-border);
	border-inline-start: 3px solid var(--wpx-accent);
	border-radius: var(--wpx-radius);
}

/* ==========================================================================
   Lists
   ========================================================================== */

.wpx-prose ul,
.wpx-prose ol {
	margin-inline: 0;
	padding-inline-start: 0;
	list-style: none;
}

.wpx-prose li {
	position: relative;
	padding-inline-start: var(--wpx-space-6);
	margin-block-end: var(--wpx-space-3);
}

.wpx-prose ul > li::before {
	content: "";
	position: absolute;
	inset-inline-start: 6px;
	top: 0.62em;
	width: 7px;
	height: 7px;
	border-radius: 2px;
	background: var(--wpx-accent);
	transform: rotate(45deg);
}

/* Numbered steps get a real numeral in an accent chip. */
.wpx-prose ol { counter-reset: wpx-step; }

.wpx-prose ol > li { counter-increment: wpx-step; padding-inline-start: var(--wpx-space-7); }

.wpx-prose ol > li::before {
	content: counter(wpx-step);
	position: absolute;
	inset-inline-start: 0;
	top: 0.1em;
	display: grid;
	place-items: center;
	width: 26px;
	height: 26px;
	background: var(--wpx-surface-3);
	border: 1px solid var(--wpx-border-strong);
	border-radius: var(--wpx-radius-pill);
	color: var(--wpx-accent);
	font-size: var(--wpx-text-xs);
	font-weight: var(--wpx-weight-bold);
	line-height: 1;
}

.wpx-prose li > ul,
.wpx-prose li > ol { margin-block-start: var(--wpx-space-2); }

/* ==========================================================================
   Tables
   ========================================================================== */

/* Wrapped so a wide spec table scrolls instead of breaking the column. */
.wpx-prose .wp-block-table,
.wpx-prose figure.wp-block-table {
	margin-inline: 0;
	overflow-x: auto;
	border-radius: var(--wpx-radius);
	border: 1px solid var(--wpx-border);
}

.wpx-prose table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--wpx-text-sm);
	background: var(--wpx-surface-1);
}

.wpx-prose thead th,
.wpx-prose table tr:first-child th {
	background: linear-gradient( 180deg, var(--wpx-surface-4), var(--wpx-surface-3) );
	color: var(--wpx-text);
	font-weight: var(--wpx-weight-bold);
	font-size: var(--wpx-text-xs);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	text-align: start;
	border-block-end: 2px solid var(--wpx-accent);
}

.wpx-prose th,
.wpx-prose td {
	padding: var(--wpx-space-3) var(--wpx-space-4);
	border-block-end: 1px solid var(--wpx-border);
	vertical-align: top;
}

.wpx-prose tbody tr:nth-child(odd) { background: rgb(from var(--wpx-surface-2) r g b / 0.55); }

.wpx-prose tbody tr:last-child th,
.wpx-prose tbody tr:last-child td { border-block-end: 0; }

.wpx-prose tbody tr { transition: background var(--wpx-transition); }
.wpx-prose tbody tr:hover { background: rgb(from var(--wpx-accent) r g b / 0.07); }

/* First column of a two-column spec table reads as the label. */
.wpx-prose tbody td:first-child,
.wpx-prose tbody th:first-child {
	color: var(--wpx-text);
	font-weight: var(--wpx-weight-medium);
	white-space: nowrap;
}

/* ==========================================================================
   Images and figures
   ========================================================================== */

.wpx-prose figure,
.wpx-prose .wp-block-image { margin-inline: 0; }

.wpx-prose img {
	border-radius: var(--wpx-radius);
	border: 1px solid var(--wpx-border);
}

.wpx-prose figcaption {
	margin-block-start: var(--wpx-space-2);
	font-size: var(--wpx-text-xs);
	color: var(--wpx-text-dim);
	text-align: center;
}

/* ---------------------------------------------------------------------------
 * Galleries: one row.
 *
 * CSS only — no script, no wrapper, no classes added at runtime. It styles
 * the markup WordPress already outputs.
 *
 * flex-direction is stated outright. That is the whole fix. Setting
 * display:flex without it left the direction to the figure rule further
 * down this file, which sets column — so every attempt at a row came out
 * as a stack, whatever width the images were given. That rule now excludes
 * galleries as well, so this is belt and braces.
 *
 * Three markups are covered:
 *   figure.wp-block-gallery > figure.wp-block-image   (current block)
 *   figure.wp-block-gallery > ul > li                 (older block)
 *   div.gallery > figure.gallery-item                 ([gallery] shortcode)
 *
 * !important throughout: wp-block-library sets flex-wrap: wrap and a width
 * on each figure with selectors carrying three classes and an element, and
 * core's stylesheet can load after the theme's.
 * ------------------------------------------------------------------------ */

.wpx-prose .wp-block-gallery,
.wpx-prose .wp-block-gallery > ul,
.wpx-prose .gallery {
	display: flex !important;
	flex-direction: row !important;
	flex-wrap: nowrap !important;
	align-items: flex-start !important;
	gap: var(--wpx-space-3) !important;
	margin: var(--wpx-space-5) 0 !important;
	padding: 0 !important;
	list-style: none !important;

	/* More images than fit simply scroll sideways. */
	overflow-x: auto;
	scroll-snap-type: x proximity;
	overscroll-behavior-x: contain;
	scrollbar-width: thin;
}

.wpx-prose .wp-block-gallery > figure,
.wpx-prose .wp-block-gallery > ul > li,
.wpx-prose .gallery > .gallery-item,
.wpx-prose .gallery > figure,
.wpx-prose .gallery > dl {
	/* Four across. The gap arithmetic multiplies a length by a plain number
	   and divides by a plain number — calc() cannot divide by a var(), and
	   doing so silently voids the whole declaration. */
	flex: 0 0 calc( ( 100% - 3 * var(--wpx-space-3) ) / 4 ) !important;
	width: calc( ( 100% - 3 * var(--wpx-space-3) ) / 4 ) !important;
	max-width: none !important;
	margin: 0 !important;
	min-width: 0;
	scroll-snap-align: start;
}

.wpx-prose .wp-block-gallery img,
.wpx-prose .gallery img {
	display: block;
	width: 100% !important;
	height: auto;
	aspect-ratio: 16 / 9;

	/* contain, not cover: these are screenshots, and cropping the sides off
	   a window removes the part being shown. */
	object-fit: contain;
	background: var(--wpx-surface-2);
	border: 1px solid var(--wpx-border);
	border-radius: var(--wpx-radius);
	margin: 0 !important;
}

/* ---------------------------------------------------------------------------
 * Keep prose styling out of the gallery.
 *
 * The older gallery block is a ul of li elements, so every image was also
 * a list item — and the prose rules gave each one an accent diamond bullet
 * and an indent to make room for it. That is where the blue diamonds
 * floating between the images came from.
 *
 * The lightbox trigger is WordPress's own button, sitting inside the
 * figure. Left alone it inherits enough to render as a solid blue slab
 * over the picture. It is kept — it is what makes the image openable —
 * but put back in the corner where it belongs.
 * ------------------------------------------------------------------------ */

.wpx-prose .wp-block-gallery li,
.wpx-prose .wp-block-gallery figure,
.wpx-prose .gallery li,
.wpx-prose .gallery .gallery-item,
.wpx-prose .gallery dl,
.wpx-prose .gallery dt {
	position: relative;
	padding-inline-start: 0 !important;
	margin-block-end: 0 !important;
	list-style: none !important;
}

.wpx-prose .wp-block-gallery li::before,
.wpx-prose .wp-block-gallery li::marker,
.wpx-prose .gallery li::before,
.wpx-prose .gallery li::marker,
.wpx-prose .gallery .gallery-item::before,
.wpx-prose .gallery dl::before,
.wpx-prose .gallery dt::before {
	content: none !important;
	display: none !important;
}

/* --- The image itself ---------------------------------------------------- */

/*
 * The inner figure of a gallery image carries the class
 * .wp-block-image, so the alignment rule near the end of this file
 * — display:flex, flex-direction:column, align-items:center — was
 * still reaching it even though the gallery itself is excluded
 * there. align-items:center shrinks a child to its content width,
 * and the img inside is width:100%, which then resolves against a
 * container with no width of its own. The images collapsed to
 * nothing and only the lightbox buttons were left on screen.
 *
 * !important rather than a longer selector: that rule sits later in
 * the file and would win on order otherwise.
 */
.wpx-prose .wp-block-gallery .wp-block-image,
.wpx-prose .wp-block-gallery figure,
.wpx-prose .gallery .gallery-icon {
	display: block !important;
	align-items: stretch !important;
	position: relative;
	margin: 0 !important;
	overflow: hidden;
	border-radius: var(--wpx-radius);
}

/* A quiet lift on hover — enough to show the image is clickable without
   the row jumping about. */
.wpx-prose .wp-block-gallery img,
.wpx-prose .gallery img {
	transition: transform var(--wpx-transition), border-color var(--wpx-transition);
}

.wpx-prose .wp-block-gallery a:hover img,
.wpx-prose .wp-block-gallery a:focus-visible img,
.wpx-prose .gallery a:hover img,
.wpx-prose .gallery a:focus-visible img {
	transform: scale(1.03);
	border-color: var(--wpx-accent);
}

@media (prefers-reduced-motion: reduce) {
	.wpx-prose .wp-block-gallery a:hover img,
	.wpx-prose .gallery a:hover img {
		transform: none;
	}
}

/* --- The lightbox button ------------------------------------------------- */

.wpx-prose .wp-lightbox-container button,
.wpx-prose .wp-block-image button.lightbox-trigger {
	position: absolute !important;
	top: var(--wpx-space-2) !important;
	inset-inline-end: var(--wpx-space-2) !important;
	inset-inline-start: auto !important;
	display: grid !important;
	place-items: center;
	width: 32px !important;
	height: 32px !important;
	min-width: 0 !important;
	padding: 0 !important;
	background: rgba(0, 0, 0, 0.55) !important;
	border: 0 !important;
	border-radius: var(--wpx-radius-sm) !important;
	color: #fff;
	opacity: 0;
	transition: opacity var(--wpx-transition);
	cursor: pointer;
}

/* Shown on hover, and always for keyboard users — an control that only
   appears on hover is unreachable without a mouse. */
.wpx-prose .wp-block-gallery .wp-block-image:hover button,
.wpx-prose .wp-lightbox-container:hover button,
.wpx-prose .wp-lightbox-container button:focus-visible {
	opacity: 1;
}

.wpx-prose .wp-lightbox-container button svg {
	width: 16px;
	height: 16px;
	fill: currentColor;
}

/* Captions sit under their image rather than over it. An overlay looks
   smarter until a caption runs to two lines and covers the picture. */
.wpx-prose .wp-block-gallery figcaption,
.wpx-prose .gallery .gallery-caption,
.wpx-prose .gallery .wp-caption-text {
	position: static !important;
	margin: var(--wpx-space-2) 0 0 !important;
	padding: 0 !important;
	background: none !important;
	font-size: var(--wpx-text-sm);
	line-height: 1.4;
	color: var(--wpx-text-muted);
	text-align: center;

	/* A long caption would otherwise stretch its column and throw the
	   row out of alignment. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Core overlays the caption on a gradient inside the figure. Undone,
   since the caption is placed below instead. */
.wpx-prose .wp-block-gallery.has-nested-images figure figcaption {
	inset: auto !important;
	background: none !important;
}

/* --- Arrow bar ------------------------------------------------------------
 *
 * Sits under the gallery, added by gallery.js. Hidden by the script
 * itself whenever every image already fits, so a short gallery does not
 * carry a pair of dead arrows.
 * ------------------------------------------------------------------------ */

.wpx-gnav {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--wpx-space-3);
	margin-block: var(--wpx-space-3) var(--wpx-space-5);
}

.wpx-gnav[hidden] { display: none; }

.wpx-gnav__arrow {
	display: grid !important;
	place-items: center;
	flex: none;
	width: 44px !important;
	height: 44px !important;
	padding: 0 !important;
	background: rgb(from var(--wpx-text) r g b / 0.28) !important;
	border: 0 !important;
	border-radius: var(--wpx-radius-pill) !important;
	color: var(--wpx-text) !important;
	box-shadow: none !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	cursor: pointer;
	transition: background var(--wpx-transition), opacity var(--wpx-transition);
}

.wpx-gnav__arrow svg {
	width: 20px;
	height: 20px;
}

/* The arrows point the way the reader is going, so they mirror on an
   RTL page along with everything else. */
[dir="rtl"] .wpx-gnav__arrow svg { transform: scaleX(-1); }

.wpx-gnav__arrow:hover:not(:disabled) {
	background: rgb(from var(--wpx-text) r g b / 0.42) !important;
}

/* Disabled rather than hidden: a control that vanishes at the ends makes
   the bar jump sideways every time you reach one. */
.wpx-gnav__arrow:disabled {
	opacity: 0.4;
	cursor: default;
}

.wpx-gnav__dots {
	display: flex;
	align-items: center;
	gap: var(--wpx-space-2);
}

.wpx-gnav__dot {
	position: relative;
	width: 9px !important;
	height: 9px !important;
	padding: 0 !important;
	background: rgb(from var(--wpx-text) r g b / 0.28) !important;
	border: 0 !important;
	border-radius: var(--wpx-radius-pill) !important;
	box-shadow: none !important;
	cursor: pointer;
	transition: width var(--wpx-transition), background var(--wpx-transition);
}

/* The active dot stretches into a pill rather than just changing colour,
   so the position is readable without relying on the accent alone. */
.wpx-gnav__dot.is-active {
	width: 30px !important;
	background: var(--wpx-accent) !important;
}

/* 9px is far below a usable touch target, so the tappable area is padded
   out without changing how the dot looks. */
.wpx-gnav__dot::before {
	content: "";
	position: absolute;
	inset: -8px;
}

.wpx-gnav__arrow:focus-visible,
.wpx-gnav__dot:focus-visible {
	outline: 2px solid var(--wpx-accent);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.wpx-gnav__dot { transition: none; }
}

/* Fewer across as the column narrows. The fractional divisors leave part of
   the next image showing, which is the only cue that the row scrolls. */
@media (max-width: 900px) {
	.wpx-prose .wp-block-gallery > figure,
	.wpx-prose .wp-block-gallery > ul > li,
	.wpx-prose .gallery > .gallery-item,
	.wpx-prose .gallery > figure,
	.wpx-prose .gallery > dl {
		flex-basis: calc( ( 100% - 2 * var(--wpx-space-3) ) / 3.2 ) !important;
		width: calc( ( 100% - 2 * var(--wpx-space-3) ) / 3.2 ) !important;
	}
}

@media (max-width: 600px) {
	.wpx-prose .wp-block-gallery > figure,
	.wpx-prose .wp-block-gallery > ul > li,
	.wpx-prose .gallery > .gallery-item,
	.wpx-prose .gallery > figure,
	.wpx-prose .gallery > dl {
		flex-basis: calc( ( 100% - 1 * var(--wpx-space-3) ) / 2.2 ) !important;
		width: calc( ( 100% - 1 * var(--wpx-space-3) ) / 2.2 ) !important;
	}
}

/* ---------------------------------------------------------------------------
 * Embeds.
 *
 * These have to work without wp-block-library. Core's responsive embed is a
 * padding-top box with the iframe absolutely positioned inside it, and that
 * stylesheet is dequeued on any post with no blocks in it — which is most
 * classic and imported content. When it goes the padding box goes with it,
 * the wrapper has no height, and an absolutely positioned iframe inside a
 * zero-height box shows nothing at all.
 *
 * aspect-ratio does the same job with no absolute positioning and no
 * dependency on another stylesheet.
 * ------------------------------------------------------------------------ */

.wpx-prose .wp-block-embed,
.wpx-prose .wp-block-video,
.wpx-video__frame {
	display: block;
	width: 100%;
	max-width: 100%;
}

.wpx-prose .wp-block-embed__wrapper {
	position: relative;
	width: 100%;
}

/*
 * Core draws its ratio box with ::before:
 *
 *   .wp-embed-responsive .wp-has-aspect-ratio .wp-block-embed__wrapper::before
 *       { content: ""; display: block; padding-top: 56.25%; }
 *
 * That box exists to reserve height for an absolutely positioned iframe.
 * The iframe here is static, so the box reserves height for nothing and
 * sits above the video as a tall empty gap.
 *
 * It needs !important. The selector above carries three classes, more
 * than anything sensible written here, so a plain override loses and the
 * padding survives.
 */
.wpx-prose .wp-block-embed__wrapper::before,
.wp-embed-responsive .wp-has-aspect-ratio .wp-block-embed__wrapper::before,
.wpx-video__frame .wp-block-embed__wrapper::before {
	content: none !important;
	display: none !important;
	padding-top: 0 !important;
}

.wpx-prose iframe,
.wpx-prose .wp-block-embed iframe,
.wpx-prose video,
.wpx-video__frame iframe {
	/* static, not absolute: core positions the iframe absolutely and leans
	   on its own padding box for height. Out of that scheme, the ratio here
	   is the only thing deciding the size. */
	position: static !important;
	display: block;
	width: 100% !important;
	max-width: 100%;
	height: auto !important;
	aspect-ratio: 16 / 9;
	border: 0;
	border-radius: var(--wpx-radius);
	background: #000;
}

/* The trailer sits in its own section on an entry page. Nothing inside it
   adds a margin: the section around it already provides the spacing, and
   a margin here would show up as a second gap above the video. */
.wpx-video__frame {
	border-radius: var(--wpx-radius);
	overflow: hidden;
	line-height: 0;
}

.wpx-video__frame > *,
.wpx-video__frame iframe,
.wpx-video__frame .wp-block-embed,
.wpx-video__frame .wp-block-embed__wrapper {
	margin: 0 !important;
}

/* Audio is a bar, not a 16:9 box. */
.wpx-prose audio,
.wpx-prose .wp-block-audio audio {
	width: 100%;
	aspect-ratio: auto;
	height: auto;
	background: none;
}

/* Portrait and square embeds keep their own shape where core has labelled
   them, so a vertical clip is not letterboxed into a widescreen frame. */
.wpx-prose .wp-embed-aspect-1-1 iframe  { aspect-ratio: 1 / 1; }
.wpx-prose .wp-embed-aspect-4-3 iframe  { aspect-ratio: 4 / 3; }
.wpx-prose .wp-embed-aspect-9-16 iframe { aspect-ratio: 9 / 16; }
.wpx-prose .wp-embed-aspect-1-2 iframe  { aspect-ratio: 1 / 2; }
.wpx-prose .wp-embed-aspect-21-9 iframe { aspect-ratio: 21 / 9; }

/* A Twitter or Facebook embed sizes itself and must not be forced to 16:9. */
.wpx-prose .wp-block-embed:not([class*="wp-embed-aspect"]) iframe[style*="height"] {
	aspect-ratio: auto;
	height: auto !important;
}

/* ==========================================================================
   Quotes, code, separators
   ========================================================================== */

.wpx-prose blockquote {
	margin-inline: 0;
	padding: var(--wpx-space-4) var(--wpx-space-5);
	background: var(--wpx-surface-2);
	border-inline-start: 3px solid var(--wpx-accent);
	border-radius: 0 var(--wpx-radius) var(--wpx-radius) 0;
	color: var(--wpx-text-muted);
}

.wpx-prose blockquote p { margin: 0; }
.wpx-prose blockquote cite { display: block; margin-block-start: var(--wpx-space-2); font-size: var(--wpx-text-sm); color: var(--wpx-text-dim); }

.wpx-prose code {
	background: var(--wpx-surface-3);
	border: 1px solid var(--wpx-border);
	padding: 0.15em 0.45em;
	border-radius: var(--wpx-radius-sm);
	font-size: 0.9em;
	color: var(--wpx-secondary);
	white-space: nowrap;
}

.wpx-prose pre {
	padding: var(--wpx-space-4);
	background: var(--wpx-surface-1);
	border: 1px solid var(--wpx-border);
	border-radius: var(--wpx-radius);
	overflow-x: auto;
}

.wpx-prose pre code { background: none; border: 0; padding: 0; white-space: pre; color: var(--wpx-text-muted); }

.wpx-prose hr,
.wpx-prose .wp-block-separator {
	border: 0;
	height: 1px;
	margin-block: var(--wpx-space-6);
	background: linear-gradient( 90deg, transparent, var(--wpx-border-strong), transparent );
}

/* ==========================================================================
   Buttons
   ========================================================================== */

/* A download button written as a block should match the theme's buttons
   rather than arriving in the editor's default blue. */
.wpx-prose .wp-block-button__link,
.wpx-prose .wp-block-buttons .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: var(--wpx-space-2);
	padding: var(--wpx-space-4) var(--wpx-space-6);
	background: linear-gradient( 135deg, var(--wpx-accent), var(--wpx-secondary) );
	color: var(--wpx-accent-ink);
	border: 0;
	border-radius: var(--wpx-radius);
	font-weight: var(--wpx-weight-bold);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	text-decoration: none;
	box-shadow: 0 8px 22px -8px rgb(from var(--wpx-accent) r g b / 0.7);
	transition: transform 220ms var(--wpx-ease-out), box-shadow 220ms var(--wpx-ease), filter 220ms var(--wpx-ease);
}

.wpx-prose .wp-block-button__link:hover {
	transform: translateY(-2px);
	filter: brightness(1.06);
	box-shadow: 0 12px 28px -8px rgb(from var(--wpx-accent) r g b / 0.85);
	color: var(--wpx-accent-ink);
}

.wpx-prose .wp-block-buttons { justify-content: center; gap: var(--wpx-space-3); }

.wpx-prose .wp-block-button.is-style-outline .wp-block-button__link {
	background: transparent;
	border: 2px solid var(--wpx-accent);
	color: var(--wpx-accent);
	box-shadow: none;
}

/* ==========================================================================
   FAQ accordions
   ==========================================================================
   Styles the native details/summary element, which is what most FAQ blocks
   and plugins output underneath.
   ========================================================================== */

.wpx-prose details {
	margin-inline: 0;
	background: var(--wpx-surface-2);
	border: 1px solid var(--wpx-border);
	border-radius: var(--wpx-radius);
	overflow: hidden;
	transition: border-color var(--wpx-transition);
}


.wpx-prose details[open] { border-color: var(--wpx-accent); }

.wpx-prose summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wpx-space-3);
	padding: var(--wpx-space-4);
	background: var(--wpx-surface-3);
	color: var(--wpx-text);
	font-weight: var(--wpx-weight-bold);
	cursor: pointer;
	list-style: none;
	transition: background var(--wpx-transition), color var(--wpx-transition);
}

.wpx-prose summary::-webkit-details-marker { display: none; }

.wpx-prose summary:hover { background: var(--wpx-surface-4); }

.wpx-prose details[open] summary { color: var(--wpx-accent); }

/* A plus that becomes a minus, drawn rather than typed so it lines up. */
.wpx-prose summary::after {
	content: "";
	position: relative;
	flex: none;
	width: 14px;
	height: 14px;
	background:
		linear-gradient( var(--wpx-accent), var(--wpx-accent) ) center / 14px 2px no-repeat,
		linear-gradient( var(--wpx-accent), var(--wpx-accent) ) center / 2px 14px no-repeat;
	transition: transform 260ms var(--wpx-ease-out);
}

.wpx-prose details[open] summary::after {
	background: linear-gradient( var(--wpx-accent), var(--wpx-accent) ) center / 14px 2px no-repeat;
	transform: rotate(180deg);
}

.wpx-prose details > *:not(summary) {
	padding: var(--wpx-space-4);
	margin: 0;
}

.wpx-prose details > *:not(summary) + *:not(summary) { padding-block-start: 0; }

/* ==========================================================================
   Mobile
   ========================================================================== */

@media (max-width: 899px) {
	.wpx-prose { font-size: var(--wpx-text-sm); }
	.wpx-prose h2 { font-size: var(--wpx-text-xl); margin-block-start: var(--wpx-space-6); }
	.wpx-prose h3 { font-size: var(--wpx-text-lg); }
	.wpx-prose th, .wpx-prose td { padding: var(--wpx-space-2) var(--wpx-space-3); }
	.wpx-prose tbody td:first-child { white-space: normal; }
	.wpx-prose .wp-block-button__link { width: 100%; justify-content: center; padding-inline: var(--wpx-space-4); }
	.wpx-prose li { padding-inline-start: var(--wpx-space-5); }
	.wpx-prose ol > li { padding-inline-start: var(--wpx-space-6); }
	.wpx-prose ol > li::before { width: 22px; height: 22px; }
}

@media (prefers-reduced-motion: reduce) {
	.wpx-prose .wp-block-button__link:hover { transform: none; }
	.wpx-prose summary::after { transition: none; }
}

/* ==========================================================================
   Alignment
   ==========================================================================
   base.css sets images to display:block for layout reasons, which silently
   cancels the text-align an editor uses to centre a picture. Handle every
   way WordPress expresses alignment, for both block and classic content.
   ========================================================================== */

/* Classic editor and pasted HTML. */
.wpx-prose img.aligncenter,
.wpx-prose figure.aligncenter,
.wpx-prose .aligncenter {
	display: block;
	margin-inline: auto;
}

.wpx-prose img.alignleft,
.wpx-prose figure.alignleft,
.wpx-prose .alignleft {
	float: left;
	margin: 0 var(--wpx-space-5) var(--wpx-space-4) 0;
	max-width: 50%;
}

.wpx-prose img.alignright,
.wpx-prose figure.alignright,
.wpx-prose .alignright {
	float: right;
	margin: 0 0 var(--wpx-space-4) var(--wpx-space-5);
	max-width: 50%;
}

.wpx-prose .alignnone { display: block; margin-inline: 0; }

/* Clear floats so a following heading is not pulled up beside an image. */
.wpx-prose h2,
.wpx-prose h3 { clear: both; }

/* Block editor: a paragraph centred in the editor holds an inline image. */
.wpx-prose p.has-text-align-center,
.wpx-prose .has-text-align-center { text-align: center; }

.wpx-prose p.has-text-align-center img,
.wpx-prose .has-text-align-center img {
	display: inline-block;
	margin-inline: auto;
}

.wpx-prose p.has-text-align-right { text-align: right; }
.wpx-prose p.has-text-align-left { text-align: left; }

/* An image block with no alignment set still centres, because a lone
   screenshot floating against the left margin reads as a mistake. */
/*
 * Embeds and galleries are excluded.
 *
 * They are figures too, so this rule was catching them. On an embed
 * align-items: center makes every child shrink to its content width,
 * and an embed wrapper's only child is an absolutely positioned
 * iframe, which has no content width at all — the wrapper collapses
 * to zero and the video disappears. This rule is only ever meant for
 * a single image.
 */
.wpx-prose .wp-block-image,
.wpx-prose figure:not(.alignleft):not(.alignright):not(.wp-block-embed):not(.wp-block-video):not(.wp-block-audio):not(.wp-block-gallery):not(.gallery) {
	display: flex;
	flex-direction: column;
	align-items: center;
}

.wpx-prose .wp-block-image img,
.wpx-prose figure:not(.alignleft):not(.alignright):not(.wp-block-embed):not(.wp-block-video):not(.wp-block-audio):not(.wp-block-gallery):not(.gallery) img {
	margin-inline: auto;
}

/* A bare image on its own line — no figure, no class — is the commonest
   case in imported content. */
.wpx-prose > p > img:only-child {
	display: block;
	margin-inline: auto;
}

.wpx-prose .alignwide,
.wpx-prose .alignfull { margin-inline: auto; }

/* ==========================================================================
   Buttons written as plain HTML
   ==========================================================================
   Imported posts often carry a download button as an anchor with its own
   class rather than a button block. Pick up the usual names so it matches
   the theme instead of arriving in the source site's colour.
   ========================================================================== */

.wpx-prose a.button,
.wpx-prose a.btn,
.wpx-prose a.download-button,
.wpx-prose a.wp-block-button__link,
.wpx-prose .su-button,
.wpx-prose .maxbutton {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--wpx-space-2);
	padding: var(--wpx-space-4) var(--wpx-space-6);
	background: linear-gradient( 135deg, var(--wpx-accent), var(--wpx-secondary) ) !important;
	color: var(--wpx-accent-ink) !important;
	border: 0;
	border-radius: var(--wpx-radius);
	font-weight: var(--wpx-weight-bold);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	text-decoration: none;
	box-shadow: 0 8px 22px -8px rgb(from var(--wpx-accent) r g b / 0.7);
	transition: transform 220ms var(--wpx-ease-out), filter 220ms var(--wpx-ease);
}

.wpx-prose a.button:hover,
.wpx-prose a.btn:hover,
.wpx-prose a.download-button:hover,
.wpx-prose .su-button:hover,
.wpx-prose .maxbutton:hover {
	transform: translateY(-2px);
	filter: brightness(1.06);
}

/* Buttons pasted in from another site arrive with their own colours, often
   from a stylesheet that loads after this one. Anything that is a link alone
   on its own line and styled like a button is normalised — matched by inline
   background, by the usual class names, and by a bare <button> in content.
   `!important` is warranted here: the competing declaration is inline. */
.wpx-prose p:has(> a[style*="background"]:only-child),
.wpx-prose p:has(> a.button:only-child),
.wpx-prose p:has(> a.btn:only-child) { text-align: center; }

/*
 * The button selector below used to end in
 * `button:not([class*="wpx-"])`, which claimed every button in the
 * content — including the lightbox trigger WordPress puts inside
 * each gallery image. That gave it the accent gradient and a 16px
 * padding, and since this rule sits far below the gallery rules,
 * it won on order even against !important. Those were the blue
 * slabs sitting over the pictures.
 *
 * Core's own controls are now excluded by name.
 */
.wpx-prose a[style*="background"]:only-child,
.wpx-prose a[style*="background-color"],
.wpx-prose a[class*="download"],
.wpx-prose a[class*="btn"],
.wpx-prose a[class*="button"]:not(.wpx-chip),
.wpx-prose button:not([class*="wpx-"]):not([class*="lightbox"]):not([class*="splide"]):not([class*="swiper"]):not([class*="slick"]):not([class*="glide"]):not([class*="flickity"]):not(.components-button):not([aria-haspopup]):not(.wp-block-navigation__responsive-container-open):not(.wp-block-navigation__responsive-container-close) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--wpx-space-2);
	padding: var(--wpx-space-4) var(--wpx-space-6) !important;
	background: linear-gradient( 135deg, var(--wpx-accent), var(--wpx-secondary) ) !important;
	background-color: transparent !important;
	color: var(--wpx-accent-ink) !important;
	border: 0 !important;
	border-radius: var(--wpx-radius) !important;
	font-weight: var(--wpx-weight-bold) !important;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	text-decoration: none !important;
	box-shadow: 0 8px 22px -8px rgb(from var(--wpx-accent) r g b / 0.7);
	transition: transform 220ms var(--wpx-ease-out), filter 220ms var(--wpx-ease);
}

.wpx-prose a[style*="background"]:hover,
.wpx-prose a[class*="download"]:hover,
.wpx-prose a[class*="btn"]:hover,
.wpx-prose a[class*="button"]:not(.wpx-chip):hover,
.wpx-prose button:not([class*="wpx-"]):not([class*="lightbox"]):not([class*="splide"]):not([class*="swiper"]):not([class*="slick"]):not([class*="glide"]):not(.components-button):hover {
	transform: translateY(-2px);
	filter: brightness(1.06);
}

/* ---------------------------------------------------------------------------
 * Stand back when a slider has taken the gallery over.
 *
 * The row layout above is for a plain gallery. When a slider plugin gets
 * hold of one it builds its own track and sizes each slide itself, usually
 * with inline styles — and the rules above, all carrying !important,
 * overrode that sizing and collapsed the track. The arrows and dots were
 * left sitting on an empty strip.
 *
 * Everything the theme imposed is handed back here. The slider then lays
 * itself out exactly as it would under any other theme, and only the
 * appearance of its controls is ours.
 * ------------------------------------------------------------------------ */

.wpx-prose .splide .wp-block-gallery,
.wpx-prose .swiper .wp-block-gallery,
.wpx-prose .slick-slider .wp-block-gallery,
.wpx-prose .wp-block-gallery:has(.splide__track),
.wpx-prose .wp-block-gallery:has(.swiper-wrapper),
.wpx-prose .wp-block-gallery:has(.slick-list) {
	display: block !important;
	overflow: visible !important;
	gap: 0 !important;
}

/*
 * Nothing is declared for slide width here, on purpose.
 *
 * An earlier version set `width: revert !important` on these, meaning
 * to hand the decision back to the slider. It did the opposite: a
 * slider sizes each slide with an inline style, and an author rule
 * carrying !important outranks an inline style. So `revert !important`
 * overwrote the real width with `auto`, the slides collapsed, and the
 * images vanished.
 *
 * Standing back means declaring nothing at all. The theme's own row
 * rules further up cannot reach these elements anyway — they match
 * direct children of .wp-block-gallery, and the slider has moved the
 * images into its own track by the time it renders.
 */

/*
 * Appearance only — no width, no height, no ratio.
 *
 * Those were here too, with !important, and they are the same trap as
 * the slide sizing above: a slider sets image dimensions inline while
 * it lays the track out, and an !important author rule overrides an
 * inline style. Forcing width:100% on an image whose slide has not
 * been measured yet is how the row ends up empty.
 *
 * The ratio the theme applies to a plain gallery is undone, because
 * that one would crop a screenshot to 16:9 inside a slide the slider
 * has already sized. `auto` without !important loses to an inline
 * value and wins over the stylesheet, which is exactly right.
 */
.wpx-prose .splide img,
.wpx-prose .swiper img,
.wpx-prose .slick-slider img {
	aspect-ratio: auto;
	object-fit: contain;
	border-radius: var(--wpx-radius);
}

/*
 * The centring rule for a single image reaches inside the slider too.
 *
 * `.wpx-prose .wp-block-image` has no exclusions on it — only the figure
 * half of that selector does — and every image the slider holds is a
 * figure.wp-block-image. It became a flex column with align-items:center,
 * which shrinks the figure to its content width; the plugin's own
 * `img { width: 100% }` then resolved against nothing, so the image was
 * zero wide and the track zero high. The arrows and dots were left
 * floating over the paragraph below.
 *
 * This is the third place that one rule has broken something — galleries,
 * then embeds, now sliders. Anything the slider owns is put back to block.
 */
.wpx-prose .splide figure,
.wpx-prose .splide .wp-block-image,
.wpx-prose .swiper figure,
.wpx-prose .swiper .wp-block-image,
.wpx-prose .slick-slider figure,
.wpx-prose .slick-slider .wp-block-image,
.wpx-prose .glide figure,
.wpx-prose .glide .wp-block-image {
	display: block !important;
	align-items: stretch !important;
	margin: 0 !important;
}

/* A slider needs its track to be able to overflow; the theme's own scroll
   container would trap it. */
.wpx-prose .splide__track,
.wpx-prose .splide__list,
.wpx-prose .swiper-wrapper,
.wpx-prose .slick-list,
.wpx-prose .slick-track {
	margin: 0 !important;
	padding-inline-start: 0 !important;
	list-style: none !important;
}

/* ---------------------------------------------------------------------------
 * Third-party sliders.
 *
 * A slider plugin — Splide, Swiper, Slick — replaces a gallery with its own
 * markup, and that markup lands inside .wpx-prose where every rule in this
 * file applies to it. Two things went wrong because of that:
 *
 *   - The pagination is a ul of li, so each dot picked up the accent
 *     diamond bullet meant for article lists. Those were the blue diamonds
 *     scattered between the images.
 *   - The arrows are plain <button> elements, so the rule for buttons
 *     pasted in from imported posts claimed them and gave each one the
 *     accent gradient and a 24px padding. Those were the blue slabs.
 *
 * The slider's own structure is left entirely alone below; only the prose
 * styling is taken back off it, and then the controls are given the
 * theme's look.
 * ------------------------------------------------------------------------ */

.wpx-prose .splide li,
.wpx-prose .swiper li,
.wpx-prose .slick-slider li,
.wpx-prose .glide li {
	padding-inline-start: 0 !important;
	margin-block-end: 0 !important;
	list-style: none !important;
}

.wpx-prose .splide li::before,
.wpx-prose .splide li::marker,
.wpx-prose .swiper li::before,
.wpx-prose .slick-slider li::before,
.wpx-prose .glide li::before {
	content: none !important;
	display: none !important;
}

/* --- Arrows -------------------------------------------------------------- */

.wpx-prose .splide__arrow,
.wpx-prose .slick-prev,
.wpx-prose .slick-next,
.wpx-prose .swiper-button-prev,
.wpx-prose .swiper-button-next {
	display: grid !important;
	place-items: center !important;
	width: 44px !important;
	height: 44px !important;
	padding: 0 !important;
	background: rgba(128, 138, 152, 0.30) !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: 999px !important;
	color: var(--wpx-text) !important;
	box-shadow: none !important;
	font-weight: 400 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	opacity: 1 !important;
	transition: background var(--wpx-transition) !important;
}

/*
 * Background only. transform is deliberately not touched here.
 *
 * A slider centres its arrows vertically with transform:
 * translateY(-50%). `transform: none` on hover wiped that out, the
 * arrow dropped by half its own height, the cursor fell off it, the
 * hover ended and it sprang back — over and over. That was the
 * shaking.
 *
 * It was only there to stop the lift from the imported-button rule,
 * and that rule no longer matches slider controls anyway.
 */
.wpx-prose .splide__arrow:hover,
.wpx-prose .slick-prev:hover,
.wpx-prose .slick-next:hover,
.wpx-prose .swiper-button-prev:hover,
.wpx-prose .swiper-button-next:hover {
	background: rgba(128, 138, 152, 0.45) !important;
}

/* Splide draws its chevron as an inline SVG. */
.wpx-prose .splide__arrow svg {
	width: 20px !important;
	height: 20px !important;
	fill: currentColor !important;
}

/* Disabled rather than hidden: a control that vanishes at the ends makes
   the bar jump sideways every time you reach one. */
.wpx-prose .splide__arrow:disabled,
.wpx-prose .slick-prev.slick-disabled,
.wpx-prose .slick-next.slick-disabled {
	opacity: 0.4 !important;
	cursor: default;
}

/* --- Pagination dots ----------------------------------------------------- */

.wpx-prose .splide__pagination,
.wpx-prose .slick-dots,
.wpx-prose .swiper-pagination {
	display: flex !important;
	align-items: center;
	justify-content: center;
	gap: 8px !important;
	margin: var(--wpx-space-3) 0 0 !important;
	padding: 0 !important;
	list-style: none !important;
}

.wpx-prose .splide__pagination__page,
.wpx-prose .slick-dots button,
.wpx-prose .swiper-pagination-bullet {
	width: 9px !important;
	height: 9px !important;
	padding: 0 !important;
	background: rgba(128, 138, 152, 0.35) !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	opacity: 1 !important;
	text-indent: -9999px;
	overflow: hidden;
	cursor: pointer;
	transition: width var(--wpx-transition), background var(--wpx-transition);
}

/* The active dot stretches into a pill rather than only changing colour, so
   the position reads without relying on the accent alone. */
/* Same reasoning: a slider may position or scale its dots with a
   transform, so that is left to it. */
.wpx-prose .splide__pagination__page.is-active,
.wpx-prose .slick-dots .slick-active button,
.wpx-prose .swiper-pagination-bullet-active {
	width: 30px !important;
	background: var(--wpx-accent) !important;
}

@media (prefers-reduced-motion: reduce) {
	.wpx-prose .splide__pagination__page { transition: none; }
}

/* ==========================================================================
   Comments
   ========================================================================== */

.wpx-comments { margin-block-start: var(--wpx-space-7); }

.wpx-comments__list {
	list-style: none;
	margin: 0 0 var(--wpx-space-6);
	padding: 0;
}

.wpx-comments__list .children {
	list-style: none;
	margin: var(--wpx-space-3) 0 0;
	padding-inline-start: var(--wpx-space-5);
	border-inline-start: 2px solid var(--wpx-border);
}

/* Beyond two levels a threaded reply has no width left, so deeper replies
   stop indenting rather than becoming a column of single words. */
.wpx-comments__list .children .children { padding-inline-start: var(--wpx-space-3); }
.wpx-comments__list .children .children .children { padding-inline-start: 0; border-inline-start: 0; }

.wpx-comment { margin-block-end: var(--wpx-space-4); }

.wpx-comment__body {
	padding: var(--wpx-space-4);
	background: var(--wpx-surface-2);
	border: 1px solid var(--wpx-border);
	border-radius: var(--wpx-radius);
}

.wpx-comment__header {
	display: flex;
	align-items: center;
	gap: var(--wpx-space-3);
	margin-block-end: var(--wpx-space-3);
}

.wpx-comment__avatar img {
	border-radius: var(--wpx-radius-pill);
	border: 1px solid var(--wpx-border-strong);
	display: block;
}

.wpx-comment__meta { display: flex; flex-direction: column; gap: 2px; }

.wpx-comment__author {
	font-weight: var(--wpx-weight-bold);
	color: var(--wpx-text);
	font-size: var(--wpx-text-sm);
}

.wpx-comment__date { font-size: var(--wpx-text-xs); color: var(--wpx-text-dim); }

.wpx-comment__content { font-size: var(--wpx-text-sm); }
.wpx-comment__content > * + * { margin-block-start: var(--wpx-space-3); }

.wpx-comment__pending {
	margin: 0 0 var(--wpx-space-3);
	padding: var(--wpx-space-2) var(--wpx-space-3);
	background: var(--wpx-surface-3);
	border-inline-start: 3px solid var(--wpx-secondary);
	font-size: var(--wpx-text-xs);
	color: var(--wpx-text-muted);
}

.wpx-comment__footer { margin-block-start: var(--wpx-space-3); }

.wpx-comment__reply a {
	font-size: var(--wpx-text-xs);
	font-weight: var(--wpx-weight-medium);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	text-decoration: none;
}

.wpx-comment.bypostauthor > .wpx-comment__body {
	border-color: var(--wpx-accent);
	box-shadow: inset 3px 0 0 var(--wpx-accent);
}

/* --- Form ---------------------------------------------------------------- */

.wpx-comments .comment-form { display: grid; gap: var(--wpx-space-4); }

.wpx-comments .comment-form p { margin: 0; }

.wpx-comments .comment-form label {
	display: block;
	margin-block-end: var(--wpx-space-2);
	font-size: var(--wpx-text-sm);
	font-weight: var(--wpx-weight-medium);
	color: var(--wpx-text);
}

.wpx-comments__notes { font-size: var(--wpx-text-xs); color: var(--wpx-text-dim); }

.wpx-comments .comment-form-cookies-consent {
	display: flex;
	align-items: center;
	gap: var(--wpx-space-2);
	font-size: var(--wpx-text-xs);
	color: var(--wpx-text-dim);
}

.wpx-comments .comment-form-cookies-consent label { margin: 0; font-weight: 400; font-size: inherit; }

.wpx-comments .comment-form-cookies-consent input { width: auto; }

.wpx-comments__closed {
	padding: var(--wpx-space-3);
	background: var(--wpx-surface-2);
	border: 1px dashed var(--wpx-border);
	border-radius: var(--wpx-radius);
	text-align: center;
	font-size: var(--wpx-text-sm);
	color: var(--wpx-text-dim);
}

/* Author, email and URL sit on one row where there is room. */
@media (min-width: 700px) {
	.wpx-comments .comment-form {
		grid-template-columns: repeat(3, 1fr);
	}

	.wpx-comments .comment-form-comment,
	.wpx-comments .comment-notes,
	.wpx-comments .comment-form-cookies-consent,
	.wpx-comments .form-submit,
	.wpx-comments .comment-reply-title { grid-column: 1 / -1; }
}

/* ==========================================================================
   Page and article headers
   ========================================================================== */

.wpx-page__header,
.wpx-article__header {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--wpx-space-3);
	margin-block-end: var(--wpx-space-5);
}

.wpx-page__cover,
.wpx-article__cover {
	margin: 0 0 var(--wpx-space-6);
}

.wpx-page__cover img,
.wpx-article__cover img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	border-radius: var(--wpx-radius-lg);
	border: 1px solid var(--wpx-border);
}

.wpx-article__cover figcaption {
	margin-block-start: var(--wpx-space-2);
	font-size: var(--wpx-text-xs);
	color: var(--wpx-text-dim);
	text-align: center;
}

/* --- Tags ---------------------------------------------------------------- */

.wpx-article__tags {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wpx-space-2);
	margin-block-start: var(--wpx-space-6);
	padding-block-start: var(--wpx-space-5);
	border-block-start: 1px solid var(--wpx-border);
}

.wpx-tag {
	padding: var(--wpx-space-1) var(--wpx-space-3);
	background: var(--wpx-surface-2);
	border: 1px solid var(--wpx-border);
	border-radius: var(--wpx-radius-pill);
	font-size: var(--wpx-text-xs);
	color: var(--wpx-text-muted);
	text-decoration: none;
	transition: border-color var(--wpx-transition), color var(--wpx-transition), transform var(--wpx-transition);
}

.wpx-tag:hover {
	border-color: var(--wpx-accent);
	color: var(--wpx-accent);
	transform: translateY(-1px);
}

/* --- Previous / next ------------------------------------------------------ */

.wpx-postnav {
	margin-block-start: var(--wpx-space-6);
	padding-block: var(--wpx-space-5);
	border-block: 1px solid var(--wpx-border);
}

.wpx-postnav .nav-links {
	display: grid;
	gap: var(--wpx-space-4);
	grid-template-columns: 1fr;
}

@media (min-width: 700px) {
	.wpx-postnav .nav-links { grid-template-columns: 1fr 1fr; }
	.wpx-postnav .nav-next { text-align: end; }
}

.wpx-postnav a {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: var(--wpx-space-3) var(--wpx-space-4);
	background: var(--wpx-surface-2);
	border: 1px solid var(--wpx-border);
	border-radius: var(--wpx-radius);
	text-decoration: none;
	transition: border-color var(--wpx-transition), transform 220ms var(--wpx-ease-out);
}

.wpx-postnav a:hover {
	border-color: var(--wpx-accent);
	transform: translateY(-2px);
}

.wpx-postnav__label {
	font-size: var(--wpx-text-xs);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--wpx-text-dim);
}

.wpx-postnav__title {
	font-size: var(--wpx-text-sm);
	font-weight: var(--wpx-weight-medium);
	color: var(--wpx-text);
	line-height: 1.35;

	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
	.wpx-postnav a:hover,
	.wpx-tag:hover { transform: none; }
}