/*
 * BLOGANO — front-end styles
 *
 * Everything below reads from the CSS custom properties defined in :root.
 * To restyle the plugin from your theme instead of editing this file, add
 * something like the block below to Appearance > Customize > Additional CSS
 * (or your child theme's stylesheet) and change any values you like:
 *
 *   :root {
 *     --psw-btn-critical-bg: #2271b1;
 *     --psw-btn-critical-bg-hover: #135e96;
 *     --psw-color-text: #1d2327;
 *     --psw-color-muted: #646970;
 *     --psw-color-card-bg: #ffffff;
 *     --psw-color-border: #dcdcde;
 *     --psw-radius: 4px;
 *     --psw-font-body: "Inter", sans-serif;
 *     --psw-font-heading: "Inter", sans-serif;
 *   }
 *
 * By default, fonts inherit your theme's fonts (--psw-font-body/heading: inherit),
 * and colors fall back to a neutral warm palette that works on most sites.
 */

/* Breaks the plugin's own screens out of the side padding many block-editor-compatible
   themes add around normal page content — the same technique WordPress's own `alignfull`
   class uses, so it reliably matches native full-width blocks placed on the same page.
   The var() fallback keeps this a safe no-op on themes that don't define the variable.
   !important is needed because this element is now the theme's own direct child, still
   targeted by the same max-width/centering rule the plugin's other elements override. */
.psw-full-bleed {
	max-width: none !important;
	margin-left: calc(var(--wp--style--root--padding-left, 0px) * -1) !important;
	margin-right: calc(var(--wp--style--root--padding-right, 0px) * -1) !important;
}
/* Which end of the bar the burger sits at.
   Applied to the mount rather than to the button inside it. With the burger switched on the
   mount becomes a block, so the button is no longer a flex item of the bar and neither an
   order nor an automatic margin on it means anything — the mount is the thing the bar is
   arranging, so the mount is the thing to move.

   With the burger off the mount is display: contents and these do nothing, which is right:
   there is no burger to place. */
/*
 * Where the burger sits — and only where there is a burger.
 *
 * These were written for every width. The mount they move is the same element that holds the
 * whole navigation when the burger is not shown, so on a desktop with the burger set to
 * mobile only they were quietly pushing the entire bar about: Burger Align centre put an
 * automatic margin on each side of every button, which is why the bar would not answer to
 * anything said about its own alignment.
 *
 * Named with the class that means the burger is on for this width, so they apply when the
 * burger does and at no other time.
 */
.psw-topbar.psw-nav-burger-desktop .psw-nav-burger-mount.psw-burger-left  { order: -1; margin-right: auto; }
.psw-topbar.psw-nav-burger-desktop .psw-nav-burger-mount.psw-burger-right { order: 1; margin-left: auto; }
.psw-topbar.psw-nav-burger-desktop .psw-nav-burger-mount.psw-burger-center { margin-left: auto; margin-right: auto; }

/* A picture in the burger takes the button's own corner. Square inside a rounded button is
   the kind of thing you see before you can name it. */
.psw-nav-burger-btn img { border-radius: var(--psw-radius-normal-btn); }

/*
 * The panel opens back towards the middle of the screen.
 *
 * Pinned to the left of its mount by default, which is right for a burger on the left and
 * wrong for one on the right — there the panel hangs off the edge of a phone, because the
 * mount is already at the far side and the panel grows away from it.
 *
 * These sit after the rule that pins it, and name the same classes it does. Written with
 * fewer, earlier, they lost twice over: on weight and on order. The panel is placed in one
 * rule for each side and nothing else has an opinion.
 */


/*
 * Which way the bar pushes its buttons.
 *
 * At the top of the file and outside every media block. The previous six attempts at this
 * were written into the narrow-screen block by accident, so they applied on a phone and
 * nowhere else — which is exactly what a bar that ignores its own setting on a desktop looks
 * like, and why nothing said about weight or order made any difference.
 *
 * Said twice on purpose: justify-content distributes the spare room, and an automatic margin
 * on the first button takes it directly. Either alone would do; neither depends on the other.
 */
.psw-topbar.psw-nav-align-left { justify-content: flex-start !important; }
.psw-topbar.psw-nav-align-center { justify-content: center !important; }
.psw-topbar.psw-nav-align-right { justify-content: flex-end !important; }

.psw-topbar.psw-nav-align-right > :first-child { margin-left: auto !important; }
.psw-topbar.psw-nav-align-center > :first-child { margin-left: auto !important; }
.psw-topbar.psw-nav-align-center > :last-child { margin-right: auto !important; }

/* ---- The archive ---- */

/* A period, and the space that says a new one has started. */
.psw-archive-period { margin: 0 0 48px; }

/* The rule moved to the row that holds both the title and the filters, or it would have
   run under the title alone and stopped short of them. */
.psw-archive-period-title { margin: 0; }

/* The heading links to itself, which is how a particular month gets a shareable address. */
.psw-archive-period-title a { color: inherit; text-decoration: none; }
.psw-archive-period-title a:hover { text-decoration: underline; }

/* Links and articles are named and counted, so the shape of a period is readable before
   any of it is. */
.psw-archive-kind {
	display: flex;
	align-items: baseline;
	gap: 8px;
	margin: 24px 0 12px;
	font-size: 14px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--psw-color-muted);
}

.psw-archive-count {
	font-size: 12px;
	padding: 1px 7px;
	border-radius: 10px;
	background: var(--psw-color-card-bg);
}

/*
 * A row: the picture, then everything else.
 *
 * Every colour, radius, border and font here comes from the same variables the cards use, so
 * the archive follows the settings without a second set of anything to keep in step.
 */
.psw-archive-rows {
	display: flex;
	flex-direction: column;
	gap: var(--psw-card-spacing, 20px);
}

/*
 * Hidden means hidden.
 *
 * The browser's own rule for [hidden] is display: none on a bare element selector, and the
 * rule above names a class — so it won, and setting the attribute did nothing at all. This
 * is why the filters appeared to be dead: they were working perfectly and changing nothing
 * anyone could see.
 */
/* A kind that is filtered out is not rendered at all now, so nothing here needs hiding —
   this stays only so that anything setting hidden still behaves. */
.psw-archive-rows[hidden] { display: none; }

/*
 * The join between the two kinds.
 *
 * Each kind is its own list and the gap belongs to the list, so it fell between articles and
 * between links but not between the last article and the first link — the one join in the
 * period with nothing holding it apart. Stated as the same spacing, so it stays in step when
 * Card Spacing changes.
 */
.psw-archive-rows + .psw-archive-rows { margin-top: var(--psw-card-spacing, 20px); }

.psw-archive-row {
	display: flex;
	align-items: stretch;
	gap: var(--psw-card-spacing, 20px);
	box-sizing: border-box;
	padding: var(--psw-card-padding, 14px);
	border: var(--psw-border-card-size) solid var(--psw-border-card-color);
	border-radius: var(--psw-radius-cards);
	background: var(--psw-color-card-bg);
	overflow: hidden;
}

/* The picture column: a share of the row, and a height of its own so one tall photograph
   cannot set the height of every row beneath it. */
.psw-archive-row-img {
	flex: 0 0 var(--psw-featured-img-width, 30%);
	max-width: var(--psw-featured-img-width, 30%);
	border-radius: var(--psw-radius-cards);
	overflow: hidden;
}

/* And every box between that column and the picture takes all of it, or a percentage of a
   self-sized box quietly becomes auto and the photograph chooses its own height. */
.psw-archive-row-img .psw-card-img-wrap,
.psw-archive-row-img a {
	display: block;
	height: 100%;
}

.psw-archive-row-img img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	border-radius: 0;
}

/*
 * Image Height and Image Ratio, the same two that shape a card's picture.
 *
 * The archive had a number of its own, which meant a site that had set either of those got
 * one answer in the feed and another here. Height when no ratio is chosen; when one is, the
 * ratio decides and the height steps aside — a box cannot obey both.
 */
.psw-archive-row-img {
	height: var(--psw-card-image-height, 180px);
}

.psw-image-ratio .psw-archive-row-img {
	height: auto;
	aspect-ratio: var(--psw-card-image-ratio, 1 / 1);
}

.psw-archive-row-body {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	/*
	 * Everything starts at the top.
	 *
	 * Without this the column spreads its children down the full height of the row, which on
	 * a short entry put a gap between the title and its own description — they belong
	 * together, and only the author and the icons belong at the foot. That one line is
	 * pushed down on its own, below.
	 */
	justify-content: flex-start;
}

/* The title and the text it introduces stay together. A card gives the description room to
   breathe under a heading; a row is read across, and the space reads as a mistake. */
.psw-archive-row-body h4 { margin: 0 0 4px; }
.psw-archive-row-body p { margin: 0 0 10px; }

/* The footer sits at the foot, as it does on a card. */
.psw-archive-row-body .psw-feed-footer { margin-top: auto; }

/* Right to left, and the picture changes sides with it. */
.psw-archive-row.psw-rtl { flex-direction: row-reverse; }

/* The way from the feed to the history. */
.psw-feed-archive-link { margin: 28px 0 0; text-align: center; }

/* Nothing matched: what was looked for, and the way back to everything. */
.psw-archive-empty {
	margin: 0 0 20px;
	color: var(--psw-color-muted);
}

.psw-archive-empty a { margin-left: 6px; }

/*
 * Two columns: the history, and the way into it.
 *
 * The list is second in the markup and first to the eye on the right, which suits both — a
 * screen reader meets the entries before a table of contents for them, and a pointer meets
 * the contents without scrolling.
 */
.psw-archive-shell {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 200px;
	gap: var(--psw-card-spacing, 20px);
	align-items: start;
}

.psw-archive-index {
	/* Stays in view down a long history. align-items: start above is what gives it somewhere
	   to travel — without that it would stretch the full height and have nothing to stick. */
	position: sticky;
	/*
	 * Where it stops, which is not where it starts.
	 *
	 * The margin below sets the starting point, level with the first card; this is only the
	 * line it will not travel above. Twenty put it under the navigation bar, which is sticky
	 * itself and gets there first.
	 */
	top: var(--psw-archive-index-top, 96px);
	/*
	 * Level with the first card rather than with the heading above it.
	 *
	 * The heading is the theme's own h2, so this is stated in the units that heading is
	 * built from: its line box plus the space below it. A theme with larger headings pushes
	 * the panel down by the same amount, because the number is in ems of the heading rather
	 * than a count of pixels.
	 *
	 * A script measured this before. It was exact and it never ran, and something that has
	 * to run to be right is worse than something close that always is.
	 */
	margin-top: var(--psw-archive-index-offset, calc(1.3em + 34px));
	padding: var(--psw-card-padding, 14px);
	border: var(--psw-border-card-size) solid var(--psw-border-card-color);
	border-radius: var(--psw-radius-cards);
	background: var(--psw-color-card-bg);
}

.psw-archive-index-title {
	display: block;
	font-size: 13px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--psw-color-muted);
}

/*
 * On a wide screen there is nothing to fold.
 *
 * The list is short, the column is doing nothing else, and a disclosure that is always open
 * is just a heading with a triangle beside it. The element stays in the markup — it is what
 * makes the phone version work without a line of script — and is simply held open here.
 */
.psw-archive-index-fold > ul { display: block; }
.psw-archive-index-fold > summary { list-style: none; cursor: default; }
.psw-archive-index-fold > summary::-webkit-details-marker { display: none; }
.psw-archive-index-fold > summary::after { content: none; }

/*
 * The period the archive is currently in, named under the heading.
 *
 * Shown at every width. The list below it leaves this one out — it is already named here —
 * so hiding it on a wide screen, as this did, removed the current month from the panel
 * altogether: the one period a reader is most likely to want.
 */
.psw-archive-index-current {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
	margin-top: 6px;
	font-size: 12px;
	color: var(--psw-color-muted);
}

.psw-archive-index-fold > summary { display: block; }

/* It is a link now, so it takes the same treatment as the ones listed below it. */
.psw-archive-index-current { color: inherit; text-decoration: none; }
.psw-archive-index-current:hover { text-decoration: underline; }

.psw-archive-index-fold > ul { margin-top: 8px; }

.psw-archive-index ul { margin: 0; padding: 0; list-style: none; }

.psw-archive-index li + li { margin-top: 2px; }

/* The period reads like the number beside it — same size, same colour. It was taking the
   theme's link styling and sat larger and louder than the count it belongs with. */
.psw-archive-index a {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
	padding: 4px 0;
	font-size: 12px;
	color: var(--psw-color-muted);
	text-decoration: none;
}

.psw-archive-index a:hover { text-decoration: underline; }

/* The period, and what is in it, on one line. */
.psw-archive-period-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	margin-bottom: 12px;
}

.psw-archive-filters {
	display: flex;
	align-items: baseline;
	gap: 6px;
	flex-shrink: 0;
}

/* Text and a number, not a button. The border and the box were doing the work of saying
   "press me" twice over, next to a heading that needs neither. */
.psw-archive-filter {
	display: inline-flex;
	align-items: baseline;
	gap: 6px;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--psw-color-muted);
	font-family: inherit;
	font-size: 12px;
	cursor: pointer;
}

.psw-archive-filter:hover { color: inherit; }

/* A button that is not the chosen one recedes rather than disappearing, so what was set
   aside is still visible and still one press from coming back. */
/* The chosen one is stated plainly; the other recedes rather than vanishing, so what was
   set aside is still visible and still one press from coming back. */
.psw-archive-filter { text-decoration: none; }
.psw-archive-filter.is-active { color: var(--psw-btn-normal-text, inherit); }
.psw-archive-filter:not(.is-active):not(.is-only) { opacity: 0.6; }

.psw-archive-filter.is-only { cursor: default; border-color: transparent; }

/* A period with only one kind in it has nothing to press. */
.psw-archive-filter.is-only:hover { background: transparent; }

/*
 * The funnel is for a narrow screen only: on a wide one the pickers are already on the row
 * and need nothing to reveal them.
 *
 * Marked important because the square-button rule it shares a row with is important too, and
 * a plain display: none loses to it however far down the file it is written — which is how
 * this ended up on the desktop after being asked for on phones only.
 */
.psw-btn.psw-filter-toggle { display: none !important; }

/* The switch is never seen — the funnel is its face. Clipped rather than display: none, so
   it can still be reached by a keyboard. */
.psw-filters-switch {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

@media (max-width: 780px) {
	/* ---- The filter row on a phone ---- */

	/* The pickers wait behind the funnel. They stay in the form either way, so a filter that
	   was set and then folded away still applies when you search. */
	.psw-feed-search select,
	.psw-filter-inline select { display: none; }

	/* Checked, and the pickers appear. No script involved: the switch sits before them in
	   the form, so it can be reached from here as their earlier sibling. */
	.psw-feed-search .psw-filters-switch:checked ~ select { display: block; }

	.psw-btn.psw-filter-toggle { display: inline-flex !important; }

	/* The burger's own placing on a phone, where a mobile burger is the thing being shown. */
	.psw-topbar.psw-nav-burger-mobile .psw-nav-burger-mount.psw-burger-left  { order: -1; margin-right: auto; }
	.psw-topbar.psw-nav-burger-mobile .psw-nav-burger-mount.psw-burger-right { order: 1; margin-left: auto; }
	.psw-topbar.psw-nav-burger-mobile .psw-nav-burger-mount.psw-burger-center { margin-left: auto; margin-right: auto; }

	/* ---- The list on a phone ---- */

	/*
	 * A row holds what it needs and no more: a picture, what the post is called, and what you
	 * can do with it. The date and the category are worth a column on a desk and worth the
	 * width of the screen on a phone — they are still on the post itself, one tap away.
	 */
	.psw-col-date,
	.psw-col-category { display: none; }

	/* The caption goes with them. A title is what you are looking for in a list; a sentence
	   under every one of them turns a list into a page of prose. */
	.psw-col-content .psw-row-caption { display: none; }

	/* What the columns gave up, the content takes. */
	.psw-col-content { width: auto; }


	/* The search row stays on one line.
	   The box is allowed to shrink and the pickers and the button are not, so a narrow screen
	   takes the width out of the field rather than dropping the button to a line of its own —
	   which on a phone leaves a button sitting alone under a search box. */
	.psw-feed-search,
	.psw-filter-inline {
		flex-wrap: nowrap;
	}

	.psw-feed-search input[type="search"],
	.psw-feed-search .psw-input {
		min-width: 0;
		flex: 1 1 auto;
	}

	.psw-feed-search select,
	.psw-filter-inline select {
		flex: 0 1 auto;
		min-width: 0;
	}

	.psw-feed-search .psw-btn,
	.psw-filter-inline .psw-btn { flex: 0 0 auto; }


	.psw-full-bleed {
		padding-left: var(--psw-mobile-side-padding, 16px);
		padding-right: var(--psw-mobile-side-padding, 16px);
		box-sizing: border-box;
	}
}

/* WordPress converts Unicode emoji characters to small inline images via its own
   core script — this guarantees they stay text-sized everywhere in the plugin,
   regardless of anything else that might otherwise catch a bare `img` selector. */
img.emoji {
	height: 1em !important;
	width: 1em !important;
	margin: 0 .07em !important;
	vertical-align: -0.1em !important;
	background: none !important;
	padding: 0 !important;
	border: none !important;
	box-shadow: none !important;
	display: inline-block !important;
	max-width: none !important;
}

:root {
	--psw-btn-critical-bg: #b3413a;
	--psw-btn-critical-bg-hover: #93332d;
	--psw-btn-critical-text: #ffffff;
	--psw-btn-critical-text-hover: #ffffff;
	--psw-btn-critical-font-size: 13px;

	--psw-btn-normal-bg: transparent;
	--psw-btn-normal-text: inherit;
	--psw-btn-normal-text-hover: inherit;
	--psw-btn-normal-bg-hover: transparent;
	--psw-btn-normal-font-size: 13px;

	/* Radius — exactly 4 govern the whole plugin. */
	--psw-radius-critical-btn: 6px;
	--psw-avatar-radius: 6px;
	--psw-radius-card-avatar: 50%;
	--psw-radius-normal-btn: 6px;
	--psw-radius-form-fields: 6px;
	--psw-radius-cards: 8px;

	/* Borders — exactly 4 govern the whole plugin. */
	--psw-border-critical-btn-color: transparent;
	--psw-border-critical-btn-size: 0px;
	--psw-border-normal-btn-color: #cccccc;
	--psw-border-normal-btn-size: 1px;
	--psw-border-card-color: #eee2d0;
	--psw-border-card-size: 1px;
	--psw-border-form-color: #eee2d0;
	--psw-border-form-size: 1px;

	--psw-color-text: inherit;
	--psw-color-muted: #6b6255;
	--psw-color-card-bg: #fbf7ef;
	--psw-color-input-bg: #ffffff;
	--psw-color-success-bg: #e9f7ef;
	--psw-color-success-text: #1e7e42;
	--psw-color-success-border: #bfe6cf;
	--psw-color-error-bg: #fbe9e7;
	--psw-color-error-text: #a5301f;
	--psw-color-error-border: #eac7c0;
	--psw-font-body: inherit;
	--psw-font-heading: inherit;
	--psw-max-width: 1000px;
}

/* No outer card/border/background on plugin sections — content extends into the page itself.
   !important here is deliberate: many themes wrap page content in a container that caps and
   centers any direct child's width (WordPress's own "constrained layout" block-editor
   convention), which would otherwise silently override the width the admin configures below. */
.psw-wizard, .psw-dashboard, .psw-feed {
	max-width: var(--psw-max-width) !important;
	margin: 0 auto !important;
	font-family: var(--psw-font-body);
	color: var(--psw-color-text);
}
@media (max-width: 780px) {
	.psw-wizard, .psw-dashboard, .psw-feed, .psw-topbar {
		max-width: 100% !important;
	}
}

/* Suppress the theme's own page-title heading on Blogano pages. We deliberately don't
   render our own page heading (per redesign feedback), so the theme's title block for
   the underlying WP page — usually .wp-block-post-title on block themes, or the classic
   entry-title/page-title class on others — needs to be hidden here so it doesn't just
   surface instead. */
body.psw-has-content .wp-block-post-title,
body.psw-has-content .entry-title,
body.psw-has-content .page-title,
body.psw-has-content h1.entry-title {
	display: none !important;
}

.psw-wizard h2, .psw-dashboard h2, .psw-feed h2 {
	font-family: var(--psw-font-heading);
}

.psw-dashboard-heading { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; gap: 16px; flex-wrap: wrap; }
.psw-dashboard-heading h2 { margin: 0; white-space: nowrap; }
.psw-dashboard-heading .psw-dashboard-filters { margin-bottom: 0; margin-left: auto; }

.psw-action-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 10px; flex-wrap: wrap; }
.psw-bulk-actions { display: flex; gap: 8px; }
.psw-bulk-actions .psw-btn:disabled, .psw-btn:disabled, .psw-btn.is-dimmed { opacity: .35; cursor: not-allowed; pointer-events: none; }
.psw-filter-inline { display: flex; align-items: stretch; gap: 8px; margin-left: auto; }
.psw-filter-inline .psw-input { max-width: 200px; }

.psw-icon-img { width: 16px; height: 16px; object-fit: contain; }

.psw-pin-panel { background: var(--psw-color-card-bg); border: var(--psw-border-form-size) solid var(--psw-border-form-color); border-radius: var(--psw-radius-form-fields); padding: 14px 16px; margin-bottom: 20px; }
.psw-pin-panel strong { display: block; margin-bottom: 10px; font-size: 13px; }
.psw-pin-panel-row { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; }
.psw-pin-panel-row label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; text-transform: uppercase; color: var(--psw-color-muted); font-weight: normal; }
.psw-pin-panel-row select { min-width: 180px; }


.psw-icon-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--psw-table-icon-size, 30px);
	height: var(--psw-table-icon-size, 30px);
	border-radius: var(--psw-radius-normal-btn);
	text-decoration: none;
	font-size: 14px;
	color: var(--psw-btn-normal-text, inherit);
	background: var(--psw-btn-normal-bg);
	border: var(--psw-border-normal-btn-size) solid var(--psw-border-normal-btn-color);
	cursor: pointer;
}
.psw-icon-btn:hover { background: var(--psw-btn-normal-bg-hover); color: var(--psw-btn-normal-text-hover, inherit); }
.psw-icon-btn-static { cursor: default; color: var(--psw-color-muted); background: transparent; border-color: transparent; }
.psw-icon-btn-static:hover { background: transparent; color: var(--psw-color-muted); }
.psw-row-actions-icons { display: flex; gap: 6px; align-items: center; height: 100%; }

.psw-thumb-wrap { position: relative; display: inline-block; width: 50px; height: 50px; }
.psw-thumb-wrap img { border-radius: calc(var(--psw-radius-critical-btn) - 4px); }
.psw-no-thumb-box { display: flex; align-items: center; justify-content: center; width: 50px; height: 50px; background: var(--psw-border-form-color); border-radius: calc(var(--psw-radius-cards) - 4px); }
.psw-thumb-avatar {
	position: absolute;
	top: -6px;
	left: -6px;
	width: 20px;
	height: 20px;
	border-radius: var(--psw-radius-card-avatar, 50%);
	box-shadow: 0 1px 3px rgba(0,0,0,.2);
	line-height: 0;
	display: block;
	overflow: hidden;
	text-decoration: none;
}
.psw-thumb-avatar img { width: 100% !important; height: 100% !important; object-fit: cover; display: block; }
.psw-row-title-link { color: var(--psw-table-text-color, inherit); text-decoration: none; font-size: var(--psw-table-text-font-size, inherit); line-height: var(--psw-table-text-line-height, normal); }
.psw-row-title-link:hover { text-decoration: underline; }
.psw-col-category a { color: var(--psw-table-text-color, inherit); text-decoration: none; }
.psw-col-category a:hover { text-decoration: underline; }
.psw-rtl .psw-thumb-avatar { left: auto; right: -6px; }
.psw-thumb-author-name { display: block; margin-top: 4px; font-size: 11px; color: var(--psw-color-muted); text-decoration: none; }
.psw-thumb-author-name:hover { text-decoration: underline; }
.psw-pin-icon { position: relative; border: none !important; }
.psw-pin-icon.is-active-pin {
	background: var(--psw-btn-normal-bg-hover);
	color: var(--psw-btn-normal-text-hover, inherit);
}
.psw-pin-badge {
	position: absolute;
	top: -6px;
	right: -6px;
	width: 15px;
	height: 15px;
	border-radius: 50%;
	background: var(--psw-attention-color, var(--psw-btn-critical-bg));
	color: #ffffff;
	border: 1px solid var(--psw-attention-color, var(--psw-btn-critical-bg));
	font-size: 9px;
	font-weight: normal;
	display: flex;
	align-items: center;
	justify-content: center;
	line-height: 1;
}

.psw-pin-widget { position: relative; display: inline-flex; }
.psw-pin-bubbles {
	position: absolute;
	bottom: calc(100% + 6px);
	left: 50%;
	transform: translateX(-50%);
	display: flex;
	gap: 4px;
	background: var(--psw-color-card-bg);
	border: var(--psw-border-form-size) solid var(--psw-border-form-color);
	border-radius: 999px;
	padding: 4px;
	box-shadow: 0 2px 10px rgba(0,0,0,.15);
	opacity: 0;
	visibility: hidden;
	transform: translateX(-50%) translateY(4px);
	transition: opacity .12s ease, transform .12s ease, visibility .12s;
	z-index: 20;
	white-space: nowrap;
}
.psw-pin-widget:hover .psw-pin-bubbles,
.psw-pin-widget.is-open .psw-pin-bubbles {
	opacity: 1;
	visibility: visible;
	transform: translateX(-50%) translateY(0);
}
.psw-pin-bubble {
	width: 22px;
	height: 22px;
	border-radius: 50%;
	border: var(--psw-border-normal-btn-size) solid var(--psw-border-normal-btn-color);
	background: var(--psw-btn-normal-bg);
	color: var(--psw-btn-normal-text, inherit);
	font-size: 11px;
	font-weight: normal;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	line-height: 1;
}
.psw-pin-bubble:hover { background: var(--psw-btn-normal-bg-hover); }
.psw-pin-bubble.is-current {
	background: var(--psw-btn-critical-bg);
	color: var(--psw-btn-critical-text);
	border-color: var(--psw-btn-critical-bg);
}

.psw-checkbox-label { display: flex; align-items: center; gap: 8px; font-size: 12px; cursor: pointer; color: var(--psw-color-muted); }
body.psw-post-rtl .entry-content,
body.psw-post-rtl .wp-block-post-content,
body.psw-post-rtl article,
body.psw-post-rtl main {
	direction: rtl;
	text-align: right;
}

/* Bio page */
/* No padding on top. The account bar is the first thing on this page and it is full-bleed,
   so any padding here shows as a strip of page above a bar that should meet the top edge.
   The bar carries its own 22px below itself, so the content underneath is unaffected. */
body.psw-bio-bare { margin: 0; padding: 0 16px 24px; box-sizing: border-box; }
/* The wrapper's usual breakout is measured against the theme's root padding, which is not
   what pads this page — the body is, at 16px. Cancelling that instead is what makes the bar
   reach both edges here rather than overshooting or falling short by the difference. */
.psw-bio-bare > .psw-topbar-wrap {
	margin-left: -16px !important;
	margin-right: -16px !important;
}

a.psw-status-toggle { cursor: pointer; text-decoration: none; border: none; }
a.psw-status-toggle:hover { filter: brightness(0.92); }

/* Top account bar, auto-injected above the plugin's own screens — single row of icon buttons */
/* The bar is a container only, on every screen size — the buttons carry the fill. Sticky
   Navigation paints the bar and its wrapper with the page colour so content can't show
   through while pinned; both are overridden here. Trade-off: with Sticky menu on, page
   content scrolls visibly behind the navigation. */
.psw-topbar,
.psw-topbar-wrap {
	background-color: transparent !important;
}
.psw-topbar {
	position: relative;
	max-width: var(--psw-max-width) !important;
	margin: 0 auto 22px !important;
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 14px 0;
	border-bottom: var(--psw-border-form-size) solid var(--psw-border-form-color);
	font-family: var(--psw-font-body);
	flex-wrap: wrap;
}
.psw-nav-burger-btn {
	display: none;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	padding: 0;
	border: var(--psw-border-normal-btn-size, 0) solid var(--psw-border-normal-btn-color, transparent);
	border-radius: var(--psw-radius-normal-btn);
	background: var(--psw-btn-normal-bg);
	color: var(--psw-btn-normal-text);
	cursor: pointer;
}
.psw-nav-collapse { display: contents; }
/* The mount is invisible to layout in normal mode — display:contents makes its children
   behave as direct flex items of the bar, exactly as they did before it existed. In burger
   mode it becomes a real box so the absolutely-positioned panel below has something to
   anchor to, which is what puts the panel under the button rather than beside it. */
.psw-nav-burger-mount { display: contents; }
.psw-nav-burger-mount.psw-nav-burger-desktop,
.psw-nav-burger-mount.psw-nav-burger-mobile { display: block; position: relative; }
.psw-topbar.psw-nav-burger-desktop .psw-nav-burger-btn,
.psw-topbar.psw-nav-burger-mobile .psw-nav-burger-btn { display: flex; }
.psw-nav-burger-mount.psw-nav-burger-desktop .psw-nav-collapse,
.psw-nav-burger-mount.psw-nav-burger-mobile .psw-nav-collapse {
	display: none;
	position: absolute;
	top: 100%;
	left: 0;
	flex-direction: column;
	align-items: stretch;
	gap: 4px;
	margin-top: 6px;
	padding: 8px;
	background: var(--psw-nav-panel-bg, var(--psw-color-card-bg));
	border: var(--psw-border-form-size) solid var(--psw-border-form-color);
	border-radius: var(--psw-radius-form-fields);
	box-shadow: 0 4px 16px rgba(0,0,0,.12);
	z-index: 100;
	min-width: 200px;
}

/* The side the panel opens from follows the side the burger sits on. Same classes as the
   rule above, so this is a decision rather than a race. */
.psw-nav-burger-mount.psw-nav-burger-desktop.psw-burger-right .psw-nav-collapse,
.psw-nav-burger-mount.psw-nav-burger-mobile.psw-burger-right .psw-nav-collapse {
	left: auto;
	right: 0;
}

/* Centred under the burger rather than under the mount. The mount is only as wide as the
   button, so half of it is the button's middle — but stating the button's own width keeps
   that true if the mount ever holds anything else. */
.psw-nav-burger-mount.psw-nav-burger-desktop.psw-burger-center .psw-nav-collapse,
.psw-nav-burger-mount.psw-nav-burger-mobile.psw-burger-center .psw-nav-collapse {
	left: 19px;
	right: auto;
	transform: translateX(-50%);
}

/* Whichever side it opens from, it cannot be wider than the screen it opens on. */
.psw-nav-burger-mount .psw-nav-collapse { max-width: calc(100vw - 24px); }
.psw-rtl .psw-nav-burger-mount.psw-nav-burger-desktop .psw-nav-collapse,
.psw-rtl .psw-nav-burger-mount.psw-nav-burger-mobile .psw-nav-collapse,
.psw-nav-burger-mount.psw-rtl.psw-nav-burger-desktop .psw-nav-collapse,
.psw-nav-burger-mount.psw-rtl.psw-nav-burger-mobile .psw-nav-collapse { left: auto; right: 0; }
/*
 * Open, because the switch is checked.
 *
 * The class this used to hang off was set by a script; the panel is now opened by the
 * checkbox that stands immediately before it. Four classes, matching the rule that closes
 * it, so the two are decided by which is true rather than by which is written later.
 */
.psw-nav-burger-mount.psw-nav-burger-desktop .psw-nav-burger-switch:checked ~ .psw-nav-collapse,
.psw-nav-burger-mount.psw-nav-burger-mobile .psw-nav-burger-switch:checked ~ .psw-nav-collapse { display: flex; }

/* The switch itself is never seen — the burger is its face — but stays reachable from a
   keyboard rather than being removed from the page. */
.psw-nav-burger-switch {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

/* A label is not a button, so it takes the pointer a button would have had. */
.psw-nav-burger-btn { cursor: pointer; }
@media (max-width: 780px) {
	.psw-topbar.psw-nav-burger-desktop:not(.psw-nav-burger-mobile) .psw-nav-burger-btn { display: none; }
	/* Burger is off at this width, so the mount must go back to being layout-transparent
	   or it would box every nav item inside a single flex child. */
	.psw-nav-burger-mount.psw-nav-burger-desktop:not(.psw-nav-burger-mobile) { display: contents; }
	.psw-nav-burger-mount.psw-nav-burger-desktop:not(.psw-nav-burger-mobile) .psw-nav-collapse { display: contents; position: static; }
}
@media (min-width: 781px) {
	.psw-topbar.psw-nav-burger-mobile:not(.psw-nav-burger-desktop) .psw-nav-burger-btn { display: none; }
	.psw-nav-burger-mount.psw-nav-burger-mobile:not(.psw-nav-burger-desktop) { display: contents; }
	.psw-nav-burger-mount.psw-nav-burger-mobile:not(.psw-nav-burger-desktop) .psw-nav-collapse { display: contents; position: static; }
}
.psw-topbar .psw-topbar-search { width: 180px !important; flex: 0 0 auto; }
.psw-topbar .psw-topbar-status { width: auto !important; flex: 0 0 auto; }
/* The bar's account controls (avatar, logout, login, register) were removed in 1.138.0;
   Blogano assumes the visitor is already signed in and leaves account and login to the
   site. Every rule that styled them went with them, including the burger-panel variants
   and the .psw-topbar-burger-label they were the only users of. */

/* RTL support (toggled via Blogano -> Settings -> Language) */
.psw-rtl { direction: rtl; text-align: right; }
.psw-rtl .psw-topbar,
.psw-topbar.psw-rtl,
.psw-rtl .psw-image-row, .psw-rtl .psw-avatar-row,
.psw-rtl .psw-field-row, .psw-rtl .psw-dashboard-heading,
.psw-rtl .psw-feed-featured,
.psw-feed-featured.psw-rtl { flex-direction: row-reverse; }
.psw-rtl .psw-table th, .psw-rtl .psw-table td { text-align: right; }
.psw-rtl .psw-actions .psw-btn-critical { margin-left: auto; margin-right: 0; }

.psw-label { display: block; font-size: 12px; font-weight: normal; letter-spacing: .02em; text-transform: uppercase; color: var(--psw-color-muted); margin-bottom: 6px; }
.psw-label-required::after { content: " *"; color: var(--psw-btn-critical-bg, #b3413a); }
.psw-field { margin-bottom: 18px; }
#psw-rtl-field-wrap { padding-top: 14px; border-top: 1px solid var(--psw-border-form-color, #eee); }
.psw-field-row { display: flex; gap: 16px; }
.psw-field-row .psw-field { flex: 1; }
/* The note under a field.
   Its top margin was negative, to pull it up under the input it belongs to. Under a label
   that has no input directly above it — the Description hint sits under the label, before
   the box — that pulled it into the words above instead. Zero, and a little space. */
.psw-field-hint { font-size: 12px; color: var(--psw-color-muted); margin: 0 0 12px; padding-top: 6px; }
/* Explanatory sentences that reuse .psw-label for size and colour but are prose, not
   field labels. .psw-label uppercases its text via text-transform, which left these
   reading as capitals on screen while the underlying text stayed sentence case — so
   copying them out produced different text than the page showed. */
.psw-note { text-transform: none; letter-spacing: 0; }
.psw-category-checkboxes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px 12px; }
.psw-category-checkboxes .psw-checkbox-label { gap: 4px; }
/* Ticked boxes take the Normal button colour instead of the browser's own blue, which is
   the one piece of chrome on this form that ignored the site's palette entirely.
   accent-color only paints the checked state; unchecked boxes stay as the browser draws
   them, and the tick contrasts automatically against whatever colour is set. */
.psw-category-checkboxes .psw-category-checkbox { accent-color: var(--psw-btn-normal-bg); }

.psw-input {
	width: 100%;
	box-sizing: border-box;
	padding: 10px 12px;
	border: var(--psw-border-form-size) solid var(--psw-border-form-color);
	border-radius: var(--psw-radius-form-fields);
	background: var(--psw-form-field-bg, var(--psw-color-input-bg));
	font-family: var(--psw-font-body);
	font-size: 14px;
	line-height: 1.5;
	color: var(--psw-form-field-text, var(--psw-color-text));
}
/* Placeholders default to a browser grey that doesn't match the "All Types" /
   "All Categories" text in the adjacent dropdowns. opacity is reset because Firefox
   applies its own to placeholders, which would lighten the colour set here. */
.psw-input::placeholder {
	color: var(--psw-form-field-text, var(--psw-color-text));
	opacity: 1;
}
.psw-input:focus {
	outline: none;
	border-color: var(--psw-btn-critical-bg);
	background: var(--psw-form-field-bg, var(--psw-color-input-bg)) !important;
	color: var(--psw-form-field-text, var(--psw-color-text)) !important;
}
select.psw-input {
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
	background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%236b6255' stroke-width='2'%3E%3Cpath d='M5 8l5 5 5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 10px center;
	background-size: 12px;
	padding-right: 32px;
}
.psw-textarea { resize: vertical; min-height: 90px; }

.psw-icon {
	width: 1em;
	height: 1em;
	vertical-align: -0.125em;
	flex-shrink: 0;
}
.psw-btn {
	display: inline-block;
	padding: 10px 18px;
	border: 1px solid transparent;
	background: none;
	font-family: var(--psw-font-body);
	font-weight: normal;
	letter-spacing: .02em;
	text-transform: uppercase;
	cursor: pointer;
	text-decoration: none;
}
.psw-btn-critical {
	background: var(--psw-btn-critical-bg);
	color: var(--psw-btn-critical-text);
	border: var(--psw-border-critical-btn-size) solid var(--psw-border-critical-btn-color);
	border-radius: var(--psw-radius-critical-btn);
	font-size: var(--psw-btn-critical-font-size);
	line-height: var(--psw-btn-critical-line-height, normal);
}
.psw-btn-critical:hover {
	background: var(--psw-btn-critical-bg-hover);
	color: var(--psw-btn-critical-text-hover);
}
.psw-btn-normal {
	background: var(--psw-btn-normal-bg);
	color: var(--psw-btn-normal-text);
	border: var(--psw-border-normal-btn-size) solid var(--psw-border-normal-btn-color);
	border-radius: var(--psw-radius-normal-btn);
	font-size: var(--psw-btn-normal-font-size);
	line-height: var(--psw-btn-normal-line-height, normal);
}
.psw-btn-normal:hover {
	background: var(--psw-btn-normal-bg-hover);
	color: var(--psw-btn-normal-text-hover);
}
.psw-btn-link { background: none; border: none; color: var(--psw-color-muted); text-transform: none; font-weight: 500; padding: 10px 6px; }
.psw-btn-block { width: 100%; text-align: center; }
.psw-icon-nav-labeled {
	display: inline-flex !important;
	align-items: center;
	gap: 6px;
	height: 38px;
	padding: 0 14px !important;
	white-space: nowrap;
	position: relative;
}
/*
 * Why the Admin button was the only one whose mark sat straight.
 *
 * Every other button in the bar holds its icon and its label directly, and several later
 * rules set that icon to inline-block for narrow screens — which drops it onto the text
 * baseline, low in a button taller than the text. The Admin one holds an inner link that
 * lays itself out again as a centred row, so the icon never reaches those rules.
 *
 * Rather than give every button that inner element, the same centring is stated for the
 * marks themselves. The Admin button is the reference; this is it, applied to the rest.
 */
.psw-topbar .psw-icon-nav-labeled > .psw-icon,
.psw-topbar .psw-icon-nav-labeled > i {
	flex: 0 0 auto;
	align-self: center;
}

.psw-nav-admin-main-link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	color: inherit;
	text-decoration: none;
}
.psw-nav-admin-wrap { position: relative; }
.psw-nav-bubble {
	position: absolute;
	top: -6px;
	right: -6px;
	min-width: 16px;
	height: 16px;
	padding: 0 4px;
	border-radius: 8px;
	background: var(--psw-attention-color, #de1414);
	color: #ffffff;
	font-size: 10px;
	font-weight: 600;
	line-height: 16px;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
}
@media (max-width: 780px) {
	.psw-topbar { gap: 4px; }
	/* The avatar on the standard mobile bar fills its button the same way it does on
	   desktop — the base 38px rule is left to apply. Inside the burger panel it stays at
	   icon size, which the higher-specificity 1em rule further up already handles. */
	.psw-topbar .psw-icon-nav-labeled span { display: none; }
	.psw-topbar .psw-icon-nav-labeled { padding: 0 !important; width: 38px; justify-content: center; }
	.psw-nav-burger-mount.psw-nav-burger-desktop .psw-nav-collapse .psw-icon-nav-labeled span,
	.psw-nav-burger-mount.psw-nav-burger-mobile .psw-nav-collapse .psw-icon-nav-labeled span {
		display: inline !important;
	}
	.psw-nav-burger-mount.psw-nav-burger-desktop .psw-nav-collapse .psw-icon-nav-labeled .psw-icon,
	.psw-nav-burger-mount.psw-nav-burger-mobile .psw-nav-collapse .psw-icon-nav-labeled .psw-icon {
		display: inline-block !important;
	}
	.psw-nav-burger-mount.psw-nav-burger-desktop .psw-nav-collapse .psw-icon-nav-labeled,
	.psw-nav-burger-mount.psw-nav-burger-mobile .psw-nav-collapse .psw-icon-nav-labeled {
		padding: 0 14px !important;
		width: auto !important;
		justify-content: flex-start !important;
	}
	/* On mobile the JS (initTopbarMobileAlign) physically moves this bar out of
	   .psw-topbar-wrap and into the page's own content container, which sits inside
	   .psw-full-bleed and therefore carries the Mobile Side Padding inset. That means
	   the "keep the sticky nav edge-to-edge" override on .psw-topbar-wrap no longer
	   reaches it — the wrapper it targets is left empty. Cancelling that inset with
	   equal negative margins, then re-adding it as padding, restores a genuinely
	   full-bleed background while keeping the icons themselves inset as before.
	   width must be auto, not 100%: 100% plus negative margins overflows horizontally
	   instead of bleeding. The !important flags are required, not stylistic — the base
	   .psw-topbar rule declares both margin and max-width with !important, so plain
	   declarations here are silently discarded no matter how specific the selector.
	   The two variables below are deliberately different and must NOT be unified:
	   the negative margin cancels the inset the PARENT applies, which is the content
	   padding, so it has to track --psw-mobile-side-padding. The padding then decides
	   where the icons sit, which is its own setting. Pointing both at the same variable
	   would put the bleed and the inset out of sync the moment the two settings differ,
	   and the background would stop short again by exactly the difference. */
	.psw-topbar.psw-topbar-in-page-parent {
		max-width: none !important;
		width: auto;
		/* Top margin is set at runtime, not here — the space above the bar comes from the
		   theme's own block spacing, which no CSS variable reliably exposes. See
		   initTopbarMobileAlign, which measures it and cancels the measured amount. */
		margin: 0 calc(var(--psw-mobile-side-padding, 16px) * -1) 22px !important;
		padding-left: var(--psw-nav-mobile-side-padding, 16px);
		padding-right: var(--psw-nav-mobile-side-padding, 16px);
		box-sizing: border-box;
		/* space-between spreads the icons evenly across the bar; the gap is a floor, so
		   they never touch on a narrow screen where there's no slack left to distribute. */
		gap: 3px;
		justify-content: space-between;
	}

/*
 * Which way the bar pushes its buttons.
 *
 * After the rule above, which sets space-between for a bar sitting inside page content.
 * Written before it and at the same weight, the setting lost on those pages and won
 * everywhere else — which is the kind of difference nobody can explain from the screen.
 */
/*
 * Which way the bar pushes its buttons.
 *
 * Plain rules again. They carried !important for a few releases while the bar refused to
 * answer them — the cause turned out to be the burger's own placing, which was moving the
 * whole nav at widths where there is no burger. With that gated, these win on their own.
 */

/*
 * And the same said with margins, which does not depend on justify-content at all.
 *
 * On a wide screen the mount and the collapse are both display: contents, so the buttons are
 * items of the bar itself — an automatic margin on the first one takes the spare room before
 * it and pushes the rest along.
 *
 * Both routes are kept deliberately. Taking them out once the burger rules were gated was
 * premature: the gating was a real fault and not the only one, and removing the workarounds
 * put the bar back where it started.
 */

/*
 * The buttons are items of the bar, and the two wrappers between them are dissolved.
 *
 * Stated rather than relied upon: the chain that collapses them is four rules deep with a
 * :not() in it, and if any link of it fails the buttons become children of a block instead
 * and nothing about the bar's arrangement reaches them.
 */
@media (min-width: 781px) {
	.psw-topbar.psw-nav-burger-mobile:not(.psw-nav-burger-desktop) .psw-nav-burger-mount,
	.psw-topbar.psw-nav-burger-mobile:not(.psw-nav-burger-desktop) .psw-nav-collapse {
		display: contents !important;
	}
}

/*
 * And the buttons themselves must not grow.
 *
 * justify-content only has something to distribute when the items leave room spare. The
 * links in this bar are anchors, which do not grow on their own — but the mount and the
 * collapse are flattened with display: contents, so whatever the page gives those children
 * is what decides. Stated here so the row cannot be filled by its own contents.
 */
.psw-topbar > *,
.psw-topbar .psw-nav-collapse > * { flex: 0 0 auto; }

	/* The bar itself stays transparent and the items keep their own button styling —
	   background, border and radius all come from the Buttons & Borders settings, the
	   same as on desktop. Width is pinned to the 38px icon square so the items plus
	   gaps and side inset still fit inside a 360px viewport. */
	.psw-topbar.psw-topbar-in-page-parent:not(.psw-nav-burger-mobile) .psw-icon-nav-labeled {
		flex: 0 0 auto !important;
		width: 38px !important;
		min-width: 0 !important;
		max-width: none !important;
		padding: 0 !important;
		justify-content: center;
	}
	/* Mobile nav presentation is fixed, and deliberately ignores the Button Style
	   (Icon / Label / Both) setting, which governs desktop only: the standard bar is
	   icon-only, because seven labelled buttons cannot fit a phone width, and the burger
	   panel is icon + label, because it is a vertical list with room for both. Without
	   the icon rule here, "Label Only" would hide the icon while the bar hides the label,
	   leaving an empty button. */
	.psw-topbar:not(.psw-nav-burger-mobile) .psw-icon-nav-labeled .psw-icon { display: inline-block !important; }
	.psw-topbar:not(.psw-nav-burger-mobile) .psw-icon-nav-labeled span { display: none !important; }
}
/* Below 340px the side inset is the first thing the standard bar gives up, so its row of
   icons keeps fitting instead of wrapping to a second line. Burger mode holds a single
   button and has no such pressure, so it keeps its Mob Nav Pad inset. */
@media (max-width: 339px) {
	.psw-topbar.psw-topbar-in-page-parent:not(.psw-nav-burger-mobile) {
		padding-left: 0;
		padding-right: 0;
	}
}
.psw-topbar.psw-critical-style-icon .psw-btn-critical.psw-icon-nav-labeled span { display: none; }
/* psw_icon() renders an <svg class="psw-icon">, never an <i> — the old selectors here
   matched nothing, so "Label Only" left the icon visible. */
.psw-topbar.psw-critical-style-label .psw-btn-critical.psw-icon-nav-labeled .psw-icon { display: none; }
/*
 * Inside the burger panel a critical button is a row like any other.
 *
 * The rule below shrinks it to a 38px square with no padding, which is what it should be in
 * the bar when Critical Style is set to icon. In the open panel it is not in the bar: it is a
 * full-width row with its icon and its words, and it was keeping the bar's padding of zero
 * while every other row had fourteen — so its icon sat a little to the left of all the rest.
 *
 * Five classes against that rule's four, and written before it, so it wins on weight rather
 * than on being further down the file.
 */
.psw-topbar .psw-nav-burger-mount .psw-nav-collapse .psw-btn-critical.psw-icon-nav-labeled {
	width: auto !important;
	padding: 0 14px !important;
	justify-content: flex-start !important;
}

.psw-topbar.psw-critical-style-icon .psw-btn-critical.psw-icon-nav-labeled { padding: 0 !important; width: 38px; justify-content: center; }
.psw-topbar.psw-normal-style-icon .psw-btn-normal.psw-icon-nav-labeled span { display: none; }
.psw-topbar.psw-normal-style-label .psw-btn-normal.psw-icon-nav-labeled .psw-icon { display: none; }
.psw-topbar.psw-normal-style-icon .psw-btn-normal.psw-icon-nav-labeled { padding: 0 !important; width: 38px; justify-content: center; }

/* The icon links keep the fixed square they have always had. They are not on a filter row
   and have nothing beside them to line up with. */
.psw-icon-nav {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	padding: 0;
}

/* One height for a filter row, and everything on it uses it.
   Chasing this by matching one control's padding to another's kept failing in a new way each
   time: the search box, the pickers and the button each worked their height out from their
   own font and padding, and no two of those agree. So the row states a height once and they
   all take it.

   It follows the Normal Button font, which is the setting anybody would expect to change the
   size of things on this row. The multiplier stands in for the line height, which cannot go
   in a calculation because its usual value is the word normal rather than a number. */
/* Defined on the page rather than on the row. On the row it reaches the controls inside it
   by inheritance, which is fine until one of them is moved or wrapped — and a variable that
   does not reach its element takes the whole declaration down with it rather than just
   itself. */
:root,
.psw-feed-search,
.psw-filter-inline {
	--psw-row-height: calc( var(--psw-btn-normal-font-size, 15px) * 1.2 + 20px );
}

/* height, not min-height.
   A minimum only lifts something shorter than the number; the search box is already taller
   than it from its own padding and font, so a minimum left it exactly where it was and the
   square button — which does take the number — stood shorter than everything beside it.
   Stated as a height, they all come out the same. */
.psw-feed-search .psw-input,
.psw-feed-search .psw-btn,
.psw-filter-inline .psw-input,
.psw-filter-inline .psw-btn {
	height: var(--psw-row-height, 38px);
	min-height: 0;
	box-sizing: border-box;
}

/* The square one is that height both ways. Stated rather than asked for with a ratio: a flex
   item sized from its contents has no definite measurement for a ratio to work from, which
   is why two attempts at aspect-ratio were ignored and the button stayed a rectangle. */
.psw-btn-square {
	/* Centred, in both directions. The rule this replaced carried these three lines and the
	   replacement did not, which left the icon sitting against the left edge of a box built
	   to hold it in the middle. */
	display: inline-flex !important;
	align-items: center;
	justify-content: center;

	/*
	 * Stated four ways, and with a fallback.
	 *
	 * The height took this and the width did not, through two releases, and I could not find
	 * the rule beating it — so rather than keep looking, every lever that decides a flex
	 * item's width is set here: width, both bounds, and the basis. One of them was being
	 * overruled; none of these can be.
	 *
	 * The fallback matters as much. A var that does not reach the element is not ignored —
	 * the whole declaration is thrown away, and the property falls back to auto, which for a
	 * button means the width of its contents. That is exactly the 38 pixels this kept
	 * measuring.
	 */
	width: var(--psw-row-height, 38px) !important;
	min-width: var(--psw-row-height, 38px) !important;
	max-width: var(--psw-row-height, 38px) !important;
	height: var(--psw-row-height, 38px) !important;
	min-height: var(--psw-row-height, 38px) !important;
	flex: 0 0 var(--psw-row-height, 38px) !important;

	padding: 0 !important;
	line-height: 0;
	align-self: center;
	box-sizing: border-box;
}

.psw-btn-square .psw-icon {
	display: block;
	width: 1.2em;
	height: 1.2em;
}

.psw-actions { display: flex; justify-content: space-between; align-items: center; margin-top: 20px; gap: 10px; }
.psw-actions .psw-btn-critical { margin-left: auto; }

.psw-alert { padding: 12px 14px; border-radius: calc(var(--psw-radius-form-fields) - 2px); font-size: 14px; margin-bottom: 16px; }
.psw-alert-error { background: var(--psw-color-error-bg); color: var(--psw-color-error-text); border: 1px solid var(--psw-color-error-border); }
.psw-alert-success { background: var(--psw-color-success-bg); color: var(--psw-color-success-text); border: 1px solid var(--psw-color-success-border); }
.psw-alert-error { background: var(--psw-color-error-bg); color: var(--psw-color-error-text); border: 1px solid var(--psw-color-error-border); }
.psw-notice { padding: 14px; background: var(--psw-color-card-bg); border-radius: calc(var(--psw-radius-form-fields) - 2px); }

.psw-image-row { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 10px; }
.psw-image-preview { width: 100px; height: 110px; object-fit: cover; border-radius: var(--psw-radius-form-fields); border: var(--psw-border-form-size) solid var(--psw-border-form-color); }
.psw-image-actions-col { display: flex; flex-direction: column; gap: 8px; flex: 1; }
.psw-image-buttons-row { display: flex; gap: 8px; }
.psw-image-buttons-row .psw-btn { flex: 1; }
.psw-visually-hidden-file-input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.psw-image-actions-col label.psw-btn { text-align: center; cursor: pointer; }
.psw-image-preview-wrap { position: relative; display: inline-block; }
.psw-image-remove-btn {
	position: absolute;
	top: -6px;
	right: -6px;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: var(--psw-btn-critical-bg, #b3413a);
	color: var(--psw-btn-critical-text, #ffffff);
	border: none;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 10px;
	cursor: pointer;
	padding: 0;
}
.psw-image-remove-btn:hover { filter: brightness(0.9); }
.psw-image-empty { font-size: 13px; color: var(--psw-color-muted); }

/* New Post: two-column layout with live preview */
.psw-new-post-columns { display: grid; grid-template-columns: 1.4fr 1fr; gap: 40px; align-items: start; max-width: 900px; margin: 0 auto; }
.psw-wizard.psw-article-active .psw-new-post-columns { grid-template-columns: 1fr; max-width: 900px; margin: 0 auto; }
.psw-post-type-toggle { display: flex; gap: 8px; margin-bottom: 16px; }
.psw-post-type-toggle .psw-btn { flex: 1; }
.psw-post-type-toggle .psw-btn.psw-post-type-active { background: var(--psw-btn-critical-bg); color: var(--psw-btn-critical-text); border-color: var(--psw-btn-critical-bg); }
.psw-report-post-wrap { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--psw-border-form-color, #eee); }
.psw-report-post-btn[disabled] { cursor: default; opacity: .7; }
.psw-url-fetch-row { display: flex; gap: 8px; }
.psw-url-fetch-row .psw-input { flex: 1; }
.psw-new-post-preview { position: sticky; top: 20px; }
@media (max-width: 900px) {
	.psw-new-post-columns { grid-template-columns: 1fr; }
	.psw-new-post-preview { position: static; }
}

.psw-preview-note { font-size: 12px; color: var(--psw-color-muted); text-align: right; margin-top: 6px; }

/* Dashboard table */
.psw-dashboard-filters { display: flex; gap: 10px; margin-bottom: 16px; }
.psw-dashboard-filters .psw-input { max-width: 260px; }
.psw-table-wrap { overflow-x: auto; }

.psw-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.psw-table th, .psw-table td { padding: 10px 12px; text-align: left; border: var(--psw-border-form-size) solid var(--psw-border-form-color); vertical-align: top; }
.psw-table th { font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--psw-table-header-text, var(--psw-color-muted)); background: var(--psw-table-header-bg, transparent); white-space: nowrap; }
.psw-table tbody tr:nth-child(odd) { background: var(--psw-table-row-odd, #ffffff); }
.psw-table tbody tr:nth-child(even) { background: var(--psw-table-row-even, #fafafa); }
.psw-sortable a { color: inherit; text-decoration: none; }
.psw-col-cb { width: 30px; }
/* Ticked boxes in both list views — My Posts and the Editorial Desk — take the Normal
   button colour, matching the category boxes on the submission form. Covers the select-all
   in the header row and the per-row boxes, since both sit in this cell. */
.psw-col-cb input[type="checkbox"] { accent-color: var(--psw-btn-normal-bg); }
.psw-row-caption { display: block; margin-top: 2px; font-size: var(--psw-table-text-font-size, 12px); line-height: var(--psw-table-text-line-height, normal); color: var(--psw-table-text-color, var(--psw-color-muted)); text-decoration: none; }
.psw-col-date { font-size: var(--psw-table-text-font-size, inherit); line-height: var(--psw-table-text-line-height, normal); color: var(--psw-table-text-color, inherit); }
.psw-row-actions a { font-size: 13px; }
.psw-row-actions .psw-delete-link { color: var(--psw-attention-color, #323232); }
.psw-no-thumb { color: var(--psw-color-muted); opacity: .6; }
.psw-status-icon { display: inline-block; margin-left: 6px; color: var(--psw-color-muted); font-size: 12px; vertical-align: middle; }
.psw-status { display: inline-block; margin-left: 6px; padding: 2px 8px; border-radius: 10px; font-size: 11px; text-transform: uppercase; font-weight: normal; }
.psw-status-draft { background: #fdf0d6; color: #9a6c14; }
.psw-status-pending { background: var(--psw-border-form-color); color: var(--psw-color-muted); }
.psw-status-publish { background: var(--psw-color-success-bg); color: var(--psw-color-success-text); }
.psw-status-future { background: #e6ecfb; color: #2f4ea8; }
.psw-status-reported { background: #fbe6e6; color: #a5301f; }
.psw-bulk-actions { margin-bottom: 10px; display: flex; gap: 8px; }
.psw-empty { text-align: center; color: var(--psw-color-muted); padding: 30px !important; }
.psw-pagination { margin-top: 16px; padding-bottom: 5px; display: flex; justify-content: center; gap: 6px; }
.psw-pagination a, .psw-pagination span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 38px;
	height: 38px;
	padding: 0 10px;
	border: var(--psw-border-normal-btn-size) solid var(--psw-border-normal-btn-color);
	border-radius: var(--psw-radius-normal-btn);
	text-decoration: none;
	color: var(--psw-btn-normal-text, inherit);
	background: var(--psw-btn-normal-bg);
	font-size: var(--psw-btn-normal-font-size);
	font-weight: normal;
}
.psw-pagination a:hover {
	background: var(--psw-btn-normal-bg-hover);
	color: var(--psw-btn-normal-text-hover, inherit);
}
.psw-pagination .current {
	background: var(--psw-btn-normal-bg-hover);
	color: var(--psw-btn-normal-text-hover, inherit);
}

.psw-filter-breadcrumb {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	padding: 8px 4px;
	margin-bottom: 16px;
	font-size: 13px;
}
/* The result count leads the filter bar. Normal weight — it sits beside the chips and
   shouldn't outrank them. */
.psw-filter-breadcrumb-count {
	font-size: 13px;
	font-weight: normal;
	color: var(--psw-color-text);
}
.psw-filter-breadcrumb-label { color: var(--psw-color-muted); font-weight: normal; }
/* The chip and the Clear all control must come out exactly the same height. That means
   matching every part of the box, not just the padding: same font-size, same explicit
   line-height, and a transparent border on the chip to answer the real border on Clear
   all. Leaving the line-height to default let the two drift apart, because one of them
   held text and the other only an icon. */
.psw-filter-breadcrumb-chip {
	background: var(--psw-border-form-color);
	color: var(--psw-color-text);
	padding: 3px 8px 3px 10px;
	border: 1px solid transparent;
	border-radius: 999px;
	font-size: 12px;
	line-height: 1.4;
	display: inline-flex;
	align-items: center;
	gap: 6px;
}
.psw-filter-breadcrumb-chip-remove {
	color: var(--psw-color-muted);
	text-decoration: none;
	/* Matches the chip label's own type and line box, so the (X) sits on the same
	   baseline and the chip keeps a single consistent height. */
	font-size: inherit;
	line-height: inherit;
}
.psw-filter-breadcrumb-chip-remove:hover { color: var(--psw-attention-color, #323232); }
/* Both rules below previously used --psw-btn-critical-bg, which is a BACKGROUND
   colour, as a text colour. On any site whose critical buttons are light — white,
   for instance — the link and its icon rendered invisibly against the page. They
   now use a foreground token that is guaranteed to contrast with page background. */
.psw-filter-breadcrumb-clear {
	color: var(--psw-attention-color, #323232);
	/* Same fill and same transparent border as a chip, so the row reads as one set of
	   controls rather than one outlined odd-one-out. */
	background: var(--psw-border-form-color);
	border: 1px solid transparent;
	text-decoration: none;
	font-weight: normal;
	font-size: 12px;
	line-height: 1.4;
	padding: 3px 10px;
	border-radius: 999px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin-left: 4px;
}
/* The background now matches the chips, so it can't carry the hover state any more. */
.psw-filter-breadcrumb-clear:hover {
	opacity: .7;
	text-decoration: none;
}

/* Avatar */
.psw-avatar { flex: 0 0 auto; border-radius: var(--psw-radius-card-avatar, 50%); object-fit: cover; }
.psw-avatar-row { display: flex; align-items: center; gap: 16px; }

/* Live feed */
/* Stretch, not centre. The search box and the pickers take their height from their own
   padding and text, a button from the button settings — so they drifted apart the moment
   either was changed. Stretched, the tallest sets the height and the rest match it, whatever
   anybody sets afterwards.

   Not done by copying the button's padding onto the input: a copied number agrees until one
   of the two changes. */
.psw-feed-search { display: flex; align-items: stretch; gap: 10px; margin-bottom: 20px; }

/* Once they stretch: an input with a height it did not choose still centres its own text,
   but a button needs telling, or its label sits at the top of a box taller than itself. */
.psw-feed-search .psw-btn,
.psw-filter-inline .psw-btn { align-items: center; }

/* A select given a height it did not ask for doubles up: its own vertical padding on top of
   the room it has been handed. */
.psw-feed-search select,
.psw-filter-inline select { padding-top: 0; padding-bottom: 0; }
.psw-feed-search input[type="search"] { flex: 1 1 auto; width: auto; min-width: 0; }
.psw-feed-search input[type="search"]::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
	height: 14px;
	width: 14px;
	background-color: currentColor;
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.146 2.146a.5.5 0 0 1 .708 0L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.146 2.146a.5.5 0 0 1 .708 0L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");
	-webkit-mask-size: contain;
	mask-size: contain;
	cursor: pointer;
}
.psw-feed-search select { flex: 0 0 auto; width: auto; min-width: 110px; max-width: 160px; }
/*
 * Nothing here wraps the search row any more.
 *
 * This block used to drop the box onto a line of its own below 640px, which is the wrapping
 * that kept coming back — it sits later in the file than the rule asking for one line, so it
 * won whatever that rule said. One line, with the box giving up width, is the whole of the
 * arrangement now.
 */
.psw-feed-search button { flex: 0 0 auto; }
.psw-feed-count { font-size: 13px; color: var(--psw-color-muted); white-space: nowrap; }
.psw-feed-cta {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	min-height: 320px;
	padding: 32px;
	border-radius: var(--psw-radius-cards);
	overflow: hidden;
	margin-bottom: var(--psw-card-spacing, 20px);
}
.psw-feed-cta-bg { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.psw-feed-cta-scrim { position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 1; pointer-events: none; }
.psw-feed-cta-content { position: relative; z-index: 2; max-width: 55%; color: #ffffff; }
.psw-feed-cta-content > *:first-child { margin-top: 0; }
.psw-feed-cta-content > *:last-child { margin-bottom: 0; }
.psw-feed-cta-form {
	position: relative;
	z-index: 2;
	flex: 0 0 320px;
	max-width: 320px;
	background: var(--psw-color-card-bg);
	border-radius: var(--psw-radius-cards);
	padding: 24px;
	box-shadow: 0 4px 24px rgba(0,0,0,.2);
	/* Held an embedded registration form until 1.137.0; now holds the two account
	   buttons, stacked. The rules that hid that form's own heading went with it. */
	display: flex;
	flex-direction: column;
	gap: 10px;
}
@media (max-width: 780px) {
	.psw-feed-cta { flex-direction: column; align-items: stretch; padding: 24px; }
	.psw-feed-cta-content { max-width: 100%; }
	.psw-feed-cta-form { flex-basis: auto; max-width: 100%; }
	.psw-table .psw-col-actions, .psw-table .psw-row-actions { display: none; }
	.psw-table tbody tr { cursor: pointer; }
}
.psw-mobile-actions-popup {
	display: none;
	position: fixed;
	z-index: 100001;
	background: var(--psw-color-card-bg, #fff);
	border: var(--psw-border-card-size, 1px) solid var(--psw-border-card-color, #eaeaea);
	border-radius: var(--psw-radius-cards, 8px);
	box-shadow: 0 4px 24px rgba(0,0,0,.2);
	padding: 10px;
	bottom: 20px;
	left: 20px;
	right: 20px;
}
.psw-mobile-actions-popup.is-open { display: block; }
.psw-mobile-actions-popup .psw-row-actions-icons { display: flex; justify-content: center; gap: 12px; }
.psw-mobile-actions-overlay {
	display: none;
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 100000;
	background: rgba(0,0,0,.3);
}
.psw-mobile-actions-overlay.is-open { display: block; }
.psw-feed-featured {
	display: flex;
	align-items: stretch;
	/* Declared rather than inherited so the featured card is exactly 370px tall and exactly
	   as wide as the content width, whatever the theme's own box-sizing happens to be. That
	   is what makes it possible to state an image size that needs no scaling: without it the
	   box is 370 plus the border on one theme and 370 including it on another. */
	box-sizing: border-box;
	height: var(--psw-featured-height, 370px);
	border: var(--psw-border-card-size) solid var(--psw-border-card-color);
	border-radius: var(--psw-radius-cards);
	background: var(--psw-color-card-bg);
	overflow: hidden;
	margin-bottom: var(--psw-card-spacing, 20px);
}
/*
 * Every featured style is the same height.
 *
 * Standard used to treat the number as a floor and grow past it, and Info Post ignored it
 * altogether — so the same setting produced three different cards and switching style
 * changed the height of the page. One number, one box, whichever style is chosen.
 *
 * The text inside scrolls or truncates as it always did rather than pushing the card taller,
 * which is what a fixed height means and why the overlay styles always had one.
 */
.psw-feed-featured:not(.psw-feed-featured-overlay):not(.psw-feed-featured-cardover):not(.psw-bio-header) {
	height: var(--psw-featured-height, 370px);
	min-height: 0;
}
.psw-feed-featured-overlay {
	display: block;
	position: relative;
	padding: 0;
	height: var(--psw-featured-height, 370px);
}
.psw-feed-featured-overlay .psw-overlay-bg { border-radius: 0; }
/* Featured Image Width. This was 42% in two places and adjustable in none — the column is
   what this governs, not the picture: Image Ratio still decides its shape and Image Height
   its height, so there is nothing here for those two to disagree with. */
/* Standard keeps the 42% it has always had. Featured Image Width was applied here, which is
   the rule every featured style shares — so setting it for Info Post silently moved
   Standard's picture too, and a column width chosen for a two-card layout left Standard's
   picture stopping well short of its own border. A setting introduced for one style should
   not reach into another that was working. */
.psw-feed-featured-img {
	flex: 0 0 42%;
	display: block;
	max-width: 42%;
	position: relative;
	height: 100%;
}

/* Featured Image Width, on the style it was built for. Same value on both properties, so a
   pixel width is not held back by a percentage cap left over from when this was
   percentage-only. */
.psw-feed-featured-infopost .psw-feed-featured-img {
	flex: 0 0 var(--psw-featured-img-width, 42%);
	max-width: var(--psw-featured-img-width, 42%);
}
/* The image sits inside .psw-card-img-wrap, which the shared renderer adds. A percentage
   height only resolves against a parent with a definite height, so without this rule the
   chain breaks at the wrapper and the picture falls back to its natural size instead of
   filling the panel. */
.psw-feed-featured-img .psw-card-img-wrap { display: block; height: 100%; }
.psw-feed-featured-img a { display: block; height: 100%; }
.psw-feed-featured-img img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 0 !important; }
/* Featured cards read the same Card Padding as everything else. They each carried their own
   fixed value, which meant the setting appeared to do nothing on whichever featured style
   was in use — and left the mobile setting with no effect there at all. */
.psw-feed-featured-body { flex: 1; display: flex; flex-direction: column; padding: var(--psw-card-padding, 14px); min-width: 0; overflow: hidden; }
/* No cap and no fade. The Caption Word Limit decides how much text there is, so cutting it
   again here meant the setting said one thing and the card showed less — the same reasoning
   that took the height cap off the cards below. The card grows instead; see the height rule
   above, which is a floor on the standard style rather than a fixed height. */
.psw-feed-featured-body p:not(.psw-bio-post-count),
.psw-feed-featured-body .psw-feed-desc-rich {
	flex: 0 0 auto;
	min-height: 0;
}
.psw-feed-featured-body .psw-feed-footer { margin-top: auto; padding-top: 10px; }

.psw-feed-meta-row { display: flex; align-items: flex-start; margin-bottom: 6px; gap: 8px; }
#psw-live-preview .psw-feed-meta-row { margin-top: 12px; }
.psw-feed-meta-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; flex: 1 1 auto; min-width: 0; }
.psw-feed-meta-row .psw-feed-date { flex-shrink: 0; white-space: nowrap; }
.psw-feed-tag, .psw-feed-date, .psw-feed-publisher { display: inline-flex; align-items: center; }
.psw-feed-tag { font-size: 10px; font-weight: normal; background: var(--psw-border-form-color); color: var(--psw-color-muted); padding: 2px 8px; border-radius: var(--psw-tag-radius, 4px); text-decoration: none; }
.psw-feed-categories-row { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0; }
.psw-feed-category-tag { font-size: 10px; font-weight: normal; background: transparent; color: var(--psw-btn-critical-bg, #b3413a); padding: 2px 8px; border-radius: var(--psw-tag-radius, 4px); text-decoration: none; }
.psw-feed-category-tag:hover { background: var(--psw-btn-critical-bg, #b3413a); color: var(--psw-btn-critical-text, #fff); }
/* The bio header's post count is styled by the same rule as the date it sits beneath:
   both are small supporting facts about the account, and sharing the rule is what keeps
   them identical without anyone having to remember to change two places. */
.psw-feed-date, .psw-bio-post-count { font-size: 12px; color: var(--psw-color-muted); text-decoration: none; }
.psw-feed-publisher { gap: 6px; font-size: 12px; color: var(--psw-color-muted); text-decoration: none; margin-bottom: 6px; }
.psw-feed-publisher .psw-avatar { width: 20px; height: 20px; }
/* On cards specifically, the publisher avatar matches the card's own action buttons
   (28px), so the footer row reads as one set of equally-weighted circles. Scoped to the
   card and the featured card deliberately — list views, the directory and the nav bar
   keep the 20px above. */
.psw-feed-card .psw-feed-publisher .psw-avatar,
.psw-feed-featured .psw-feed-publisher .psw-avatar {
	/* Card Avatar Size. This is the rule that has always sized a card avatar, so this is
	   where the setting has to go — a rule on .psw-avatar alone carries one class against
	   these two and loses, whatever value it emits. It defaults to the 28px described
	   above, so a site that never touches the setting looks exactly as it did. */
	width: var(--psw-card-avatar-size, 28px);
	height: var(--psw-card-avatar-size, 28px);
}
.psw-feed-featured h3, .psw-feed-featured a { color: inherit; text-decoration: none; }
/* Size and colour come from the theme's own h3; the margin, the heading font and the
   weight are ours. Normal weight is deliberate and matches the card titles below: a card
   title is a label on a card, not a page heading, and the featured card is the same thing
   at a larger size. The theme's h3 weight was briefly allowed through in 1.72.0 and made
   the featured title the only bold thing in the feed. */
.psw-feed-featured h3 { margin: 6px 0 8px; font-family: var(--psw-font-heading); font-weight: normal; }
/* Space between the meta row and the title in standard mode. Excludes the bio header,
   where the post count already sits in that gap and the extra room is not wanted. */
.psw-feed-featured:not(.psw-bio-header):not(.psw-feed-featured-overlay):not(.psw-feed-featured-cardover) h3 {
	margin-top: 16px;
}
/* Sits above the name now, so the pull-up that used to tuck it under the name would drag
   it into the meta row instead. No font-size or colour of its own either: it is a caption,
   and leaving those out lets it read consistently with the rest of the header. */
.psw-bio-post-count { margin: 0 0 2px; }
/* The name is a link inside the heading, and a link brings its own colour, which would beat
   the title colour set on the heading. Inheriting is what makes the name match a card
   title, where the colour sits on the heading and there is no link inside it. */
.psw-bio-header h3 a { color: inherit; }
/* pre-line keeps the paragraph breaks the description carries while still collapsing runs
   of spaces, so a multi-paragraph article reads as paragraphs on its card instead of one
   run-on block. The text itself is plain — the breaks are newlines, not markup. */
.psw-feed-featured p, .psw-feed-card p { color: var(--psw-color-muted); margin: 0 0 10px; white-space: pre-line; }

/* Formatted card text. A card is a fixed box and an article is not, so the text is capped
   and faded rather than allowed to set the card's height — otherwise one long post makes
   its whole grid row as tall as itself. The cap is generous enough that most cards never
   reach it.

   The elements inside are brought back to card scale: an article's h2 is sized for a page
   and would dwarf the card's own title, and default list and paragraph margins leave gaps
   that read as broken spacing at this size. Colours, weights and emphasis are left exactly
   as written, which is the point of the setting. */
.psw-feed-desc-rich {
	color: var(--psw-color-muted);
	margin: 0 0 10px;
}
.psw-feed-desc-rich > *:first-child { margin-top: 0; }
.psw-feed-desc-rich > *:last-child { margin-bottom: 0; }
/* color:inherit matters here. The card's own rule colours every <p> inside a card, which
   used to mean only the description itself — now the description can contain paragraphs,
   and that rule was recolouring them to the muted tone while the list items beside them
   kept the description colour. Two shades in one block, from one element being a <p> and
   the other not. Inheriting puts everything back on the block's colour. */
.psw-feed-desc-rich p { margin: 0 0 .6em; white-space: normal; color: inherit; }
/* Links written into formatted card text. They are no longer inside the card's own link,
   so they need the theme's link colour back — without this they inherit the muted
   description colour and are indistinguishable from the words around them. */
.psw-feed-desc-rich a { color: var(--psw-btn-normal-text, inherit); text-decoration: underline; }
.psw-feed-desc-rich ul,
.psw-feed-desc-rich ol { margin: 0 0 .6em; padding-left: 1.2em; }
/* Close to the paragraph's .6em rather than half of it. Lines packed twice as tightly put
   more ink in the same area, which reads as darker text even though the colour is identical
   — the list and the paragraph both inherit their colour from this block. */
.psw-feed-desc-rich li { margin: 0 0 .5em; }
.psw-feed-desc-rich h1,
.psw-feed-desc-rich h2,
.psw-feed-desc-rich h3,
.psw-feed-desc-rich h4,
.psw-feed-desc-rich h5,
.psw-feed-desc-rich h6 { font-size: 1.1em; line-height: 1.3; margin: 0 0 .4em; }
.psw-feed-desc-rich img { max-width: 100%; height: auto; }
.psw-feed-desc-rich table { width: 100%; font-size: .95em; }
.psw-feed-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }
.psw-feed-footer-icons { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.psw-feed-footer .psw-feed-publisher { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.psw-feed-readmore { font-size: 13px; font-weight: normal; color: var(--psw-attention-color, #323232); text-decoration: none; }
.psw-feed-share, .psw-feed-external-link, .psw-feed-edit {
	width: 28px;
	height: 28px;
	padding: 0 !important;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: var(--psw-icon-font-size, 13px);
	line-height: var(--psw-icon-line-height, normal);
	color: var(--psw-icon-color) !important;
	background: var(--psw-icon-bg) !important;
	border: var(--psw-icon-border-size, 0) solid var(--psw-icon-border-color, transparent) !important;
	border-radius: var(--psw-icon-radius, 4px);
}
.psw-feed-share:hover, .psw-feed-external-link:hover, .psw-feed-edit:hover {
	color: var(--psw-icon-color-hover) !important;
	background: var(--psw-icon-bg-hover) !important;
}
.psw-feed-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--psw-card-spacing, 20px); margin-bottom: var(--psw-card-spacing, 20px); }
.psw-feed-card {
	display: flex;
	flex-direction: column;
	height: 100%;
	border: var(--psw-border-card-size) solid var(--psw-border-card-color);
	border-radius: var(--psw-radius-cards);
	background: var(--psw-color-card-bg);
	overflow: hidden;
	padding: var(--psw-card-padding, 14px);
}
.psw-feed-card > .psw-card-img-wrap { margin: 10px calc(var(--psw-card-padding, 14px) * -1); }
.psw-card-img-wrap { display: block; position: relative; }
.psw-feed-card-img { display: block; padding: 0 !important; margin: 0 !important; }
/* The image is pulled out by exactly the card's own padding, on every side, so it meets the
   edges however much padding the text is given. Sideways was missing: the image cleared the
   top but stayed inset left and right, which read as a border around the picture and got
   wider as the padding went up. All four read the same token, which is what keeps them in
   step — they can never disagree with the padding they are cancelling. */
.psw-feed-card > .psw-card-img-wrap:first-child {
	margin-top: calc(var(--psw-card-padding, 14px) * -1);
	margin-left: calc(var(--psw-card-padding, 14px) * -1);
	margin-right: calc(var(--psw-card-padding, 14px) * -1);
}
.psw-feed-card > .psw-card-img-wrap:first-child:last-child { margin-bottom: calc(var(--psw-card-padding, 14px) * -1); }
.psw-feed-card-img img { width: 100%; height: var(--psw-card-image-height, 140px); object-fit: cover; display: block; padding: 0 !important; margin: 0 !important; }
/* Full image has no card behind it. The border and padding came off, but the background
   did not — so the card colour carried on painting under the text beneath the picture,
   which is the one place a full-image card is meant to have nothing behind it. */
.psw-feed-card-full-image { border: none; padding: 0; background: none; }
.psw-feed-card-full-image > .psw-card-img-wrap,
.psw-feed-card-full-image > .psw-card-img-wrap:first-child { margin: 0 0 10px 0; }
.psw-feed-card-full-image > .psw-card-img-wrap:first-child:last-child { margin: 0 0 var(--psw-card-spacing, 20px) 0; }
/* Every box that clips the picture carries the same radius, so all four corners survive.
   A rounded image inside a square clipping box loses the corners at whichever edge is doing
   the clipping — which is why the radius appeared to apply only at the top. */
.psw-feed-card-full-image .psw-card-img-wrap,
.psw-feed-card-full-image .psw-feed-card-img {
	display: block;
	border-radius: var(--psw-radius-cards);
	overflow: hidden;
}
.psw-feed-card-full-image .psw-feed-card-img img {
	height: var(--psw-card-image-height, 260px);
	object-fit: cover;
	border-radius: var(--psw-radius-cards);
	border: var(--psw-border-card-size) solid var(--psw-border-card-color);
}
/* One ratio, all three card styles. The shape itself comes from the variable rather than
   from the class, so adding a ratio to the settings needs no new CSS — and the three styles
   cannot end up supporting different sets of ratios, which is how Square came to work
   everywhere except standard cards.

   Placed after the height rules so it wins: an image with a ratio has no height of its own
   to set, which is why the ratio takes precedence over Card Image Height. */
.psw-image-ratio .psw-feed-card-img img,
.psw-image-ratio .psw-feed-card-full-image .psw-feed-card-img img {
	height: auto;
	width: 100%;
	aspect-ratio: var(--psw-card-image-ratio, 1 / 1);
}
/* Overlay has no separate image to shape — the card is the picture — so the ratio goes on
   the card and its height floor comes off. */
.psw-image-ratio .psw-feed-card-overlay {
	min-height: 0;
	aspect-ratio: var(--psw-card-image-ratio, 1 / 1);
}
.psw-feed-card h4, .psw-feed-card a { color: inherit; text-decoration: none; }
/* No size here. A card title is an h4 and takes the theme's own, the way the featured
   card's h3 already did — the two were inconsistent for no reason. Font Size under What to
   Display sets it when you want something else, and setting nothing now means the theme
   decides rather than a number chosen years ago in somebody else's stylesheet. */
.psw-feed-card h4 { margin: 6px 0; font-family: var(--psw-font-heading); font-weight: normal; }
.psw-feed-card .psw-feed-footer { margin-top: auto; padding-top: 10px; }
@media (max-width: 780px) {
	.psw-feed-grid { grid-template-columns: repeat(var(--psw-columns-mobile, 1), 1fr) !important; gap: var(--psw-card-spacing-mobile, 12px); margin-bottom: var(--psw-card-spacing-mobile, 12px); }
	.psw-directory-page .psw-feed-grid { grid-template-columns: repeat(var(--psw-dir-columns-mobile, 1), 1fr) !important; }
	.psw-feed-card-full-image > .psw-card-img-wrap,
	.psw-feed-card-full-image > .psw-card-img-wrap:first-child { margin: 0 0 10px 0; }
	.psw-feed-card-full-image > .psw-card-img-wrap:first-child:last-child { margin: 0 0 var(--psw-card-spacing-mobile, 12px) 0; }
}

/* Overlay card style — image fills the whole card, text sits on top */
.psw-feed-card-overlay {
	display: block;
	position: relative;
	padding: 0;
	/* Overlay has no separate <img> to size, so the card's own height carries the setting. */
	min-height: var(--psw-card-overlay-min-height, 260px);
}
.psw-overlay-bg { position: absolute; top: 0; right: 0; bottom: 0; left: 0; display: block; z-index: 1; }
.psw-overlay-bg img,
.psw-overlay-bg .psw-fallback-image { width: 100%; height: 100%; object-fit: cover; display: block; }
.psw-overlay-scrim {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 2;
	background: linear-gradient(to top, rgba(0,0,0,.75) 0%, rgba(0,0,0,.35) 45%, rgba(0,0,0,0) 75%); /* fallback if inline style is ever missing */
	pointer-events: none;
}
.psw-overlay-top {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 3;
	display: flex;
	align-items: flex-start;
	justify-content: flex-start;
	gap: 8px;
	padding: 12px;
}
.psw-overlay-top .psw-feed-meta-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; flex: 1 1 auto; min-width: 0; }
.psw-overlay-top .psw-feed-date { flex-shrink: 0; white-space: nowrap; }
.psw-overlay-bottom {
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 3;
	padding: var(--psw-card-padding, 14px) var(--psw-card-padding, 14px) 46px;
}
.psw-overlay-bottom h4 { margin: 4px 0; font-weight: normal; }
.psw-overlay-bottom p { margin: 0; opacity: .9; }
/* The footer sits on top of this block rather than after it, so the only thing keeping the
   description off the publisher avatar is this bottom padding. The featured overlay is
   taller and its description runs longer, so it needs more clearance than a card does. */
.psw-feed-featured-overlay .psw-overlay-bottom { padding-bottom: 58px; }
.psw-feed-card-overlay .psw-feed-footer,
.psw-feed-featured-overlay .psw-feed-footer {
	position: absolute;
	bottom: 10px;
	right: 10px;
	left: 10px;
	z-index: 4;
	margin-top: 0;
	padding-top: 0;
}

/* Toast notifications, bottom-right */
.psw-toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 100000; display: flex; flex-direction: column; gap: 8px; }
.psw-toast-container .psw-alert { box-shadow: 0 4px 16px rgba(0,0,0,.12); margin-bottom: 0; min-width: 220px; }

/* User Directory member cards — blurred background + sharp centered avatar */
.psw-dir-card-img {
	position: relative;
	height: 140px;
	overflow: hidden;
	margin: calc(var(--psw-card-padding, 14px) * -1) calc(var(--psw-card-padding, 14px) * -1) 10px;
	display: block;
}
.psw-dir-card-bg {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	filter: blur(20px);
	transform: scale(1.15);
}
.psw-dir-card-avatar {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 80px;
	height: 80px;
	border-radius: var(--psw-radius-card-avatar, 50%);
	object-fit: cover;
}
.psw-dir-card h4 { margin: 6px 0 2px; }
/* No font-size here on purpose. Post card descriptions set none and inherit, so pinning
   these to 13px made the two kinds of card disagree whenever the description size setting
   was left empty — which is the default. Both now come from the same place: your setting
   when it is set, inherited when it is not. */
.psw-dir-card p:not(.psw-feed-publisher) { margin: 0; color: var(--psw-color-muted); }
.psw-dir-card-bio { margin-bottom: 6px !important; }

/* Bio page: admin-only role-change control */
.psw-bio-role-change { display: flex; align-items: center; gap: 10px; margin-bottom: var(--psw-card-spacing, 20px); }
.psw-bio-role-change label { font-size: 13px; color: var(--psw-color-muted); }
.psw-bio-role-change select { width: auto; }
.psw-bio-role-notice { flex-basis: 100%; margin: 0 0 6px; font-size: 13px; color: var(--psw-color-muted); }

/* Basic table styling for Summernote-inserted tables — WordPress's default post
   content KSES context already allows table/tr/td/th, but adds no visible borders
   of its own, so a table would otherwise look unstyled/broken to readers. Covers
   both the article's own single-post page (WordPress theme's standard .entry-content
   wrapper) and the CTA content block.

   Every selector here excludes .psw-table. The plugin's own dashboard tables render
   inside the theme's .entry-content wrapper too, so without :not() these rules match
   them as well — and at higher specificity than .psw-table's own rules, which silently
   overrode the Table Design settings (notably Header Background). :not() adds no
   specificity of its own, so content tables are unaffected. */
.entry-content table:not(.psw-table), .psw-feed-cta-content table:not(.psw-table) {
	border-collapse: collapse;
	width: 100%;
	margin: 12px 0;
}
.entry-content table:not(.psw-table) th, .entry-content table:not(.psw-table) td,
.psw-feed-cta-content table:not(.psw-table) th, .psw-feed-cta-content table:not(.psw-table) td {
	border: var(--psw-border-form-size, 1px) solid var(--psw-border-form-color, #e0e0e0);
	padding: 8px 10px;
	text-align: left;
}
.entry-content table:not(.psw-table) th, .psw-feed-cta-content table:not(.psw-table) th {
	font-weight: 600;
	background: rgba(0,0,0,.03);
}

/* Summernote containment. The editor ships with no width ceiling of its own, so wide
   pasted content — a table, a large image, a long unbroken URL — pushed the editor
   past its column and dragged the whole page layout out with it. Constraining the
   editable area and its common wide children keeps the overflow inside the editor,
   where it scrolls, instead of escaping into the page. */
.note-editor { max-width: 100%; box-sizing: border-box; }
.note-editor .note-editable {
	max-width: 100%;
	overflow-x: auto;
	overflow-wrap: break-word;
	word-wrap: break-word;
}
.note-editor .note-editable img { max-width: 100%; height: auto; }
.note-editor .note-editable table { max-width: 100%; table-layout: fixed; }
.note-editor .note-editable td, .note-editor .note-editable th { overflow-wrap: break-word; }
.note-editor .note-editable pre { white-space: pre-wrap; word-break: break-word; }

/* --------------------------------------------------------------- Featured: Info Post */

/* Two columns, like Standard, with nothing shared between them.
   Standard wraps both in one bordered box, which is why its picture has to have square
   corners — a rounded image inside a rounded box leaves four slivers of card showing at the
   corners. Here the columns are separate objects, so the picture can carry the card radius
   itself and the text sits beside it rather than inside the same frame. */
.psw-feed-featured-infopost {
	border: none;
	background: none;
	overflow: visible;
	gap: var(--psw-card-spacing, 20px);
	/*
	 * The same height as every other featured style.
	 *
	 * This had none, on the reasoning that without a frame around them the two columns have
	 * no reason to match and a short article should not leave a tall empty panel beside its
	 * picture. That holds on its own terms, but it made Info Post the one style that changed
	 * the height of the page when chosen — and a setting that means something different in
	 * each style is not really one setting.
	 */
	height: var(--psw-featured-height, 370px);
	/*
	 * Stretch, now that the card has a height of its own.
	 *
	 * This was flex-start so each column could take its own height — right when the card had
	 * none. With a stated height the reasoning inverts: flex-start let the picture's column
	 * size itself to the picture, and a tall portrait then drew straight through the cards
	 * below, because the card can no longer grow to hold it and nothing clips it.
	 */
	align-items: stretch;
}

.psw-feed-featured-infopost .psw-feed-featured-img {
	/* Its own object now, so it takes the card radius and the card border. */
	border-radius: var(--psw-radius-cards);
	border: var(--psw-border-card-size) solid var(--psw-border-card-color);
	overflow: hidden;
	/* The card's height. This said auto, from when the card had none — and being written
	   later than the rule that asks for the card's height, it quietly undid it. */
	height: 100%;
}
/* The shared rule squares every featured picture with an !important, which is right: in
   Standard, Overlay and Cardover the box around the picture is what carries the corners.
   Info Post is the same — its column has the radius and clips — so nothing needs answering
   here any more. */
.psw-feed-featured-infopost .psw-feed-featured-img img {
	/* No radius on the picture. The column around it already has one and clips, so the
	   rounded shape comes from there — a second radius here only adds an !important that
	   exists to fight another !important, and makes the corners impossible to change from
	   one place. Every other featured style squares its picture and lets the box round it;
	   this is the same arrangement. */
	height: 100%;
	/* No floor, and cropped to the column. A minimum height inside a box of a stated height
	   is another way of spelling overflow: it was 260, the card is 370, and a portrait
	   photograph took all of what it wanted and ran through the row beneath. */
	min-height: 0;
	object-fit: cover;
}

/* Nothing in the text column brings a margin of its own to the top. The padding is already
   zero, but a heading or a meta row carries its own spacing from the theme, which is what
   was still holding the first line below the top of the picture. */
.psw-feed-featured-infopost .psw-feed-featured-body > *:first-child,
.psw-feed-featured-infopost .psw-feed-featured-body > *:first-child > *:first-child {
	margin-top: 0;
	padding-top: 0;
}
.psw-feed-featured-infopost .psw-feed-featured-body {
	/* No frame and no padding. The border belongs to the picture, and padding inside a
	   panel that has no edges only pushes the text away from a boundary that is not there —
	   it stopped the first line sitting level with the top of the picture. The space between
	   the two columns is the gap on the row, which is Card Spacing, so this matches every
	   other card without a number of its own. */
	border: none;
	background: none;
	padding: 0;
	justify-content: flex-start;
}

/* The Info Post ratio is applied in the markup — see the renderer.
   There is deliberately no rule here for the chain inside the frame. There was one, meant to
   stop the chain imposing a height of its own, and it carried four classes against the two
   of the rule that makes the picture fill — so it won, the wrapper collapsed to the
   picture's natural height, and the picture sat short inside a perfectly square frame. A
   rule written to avoid contradicting the frame was the only thing contradicting it.
   The column itself still needs releasing, since it is outside the frame. */
/* And the column keeps the card's height whether or not a ratio is set. It was released to
   auto here so the frame could decide the shape; there is no frame on a featured card any
   more, so releasing it only let the picture size itself again. */
.psw-image-ratio .psw-feed-featured-infopost .psw-feed-featured-img {
	height: 100%;
	min-height: 0;
}

/* Info Post on a phone is handled with every other style, in the one block above. This
   held its own copy at a second breakpoint, and the two disagreed. */


/* Cardover featured post — full-bleed photo with a card panel floating over it. The panel
   carries the standard card's content stack, so Caption Word Limit and the What to Display
   toggles govern it exactly as they govern the cards below. No scrim: the panel's own
   background provides the contrast, which is why the Overlay Scrim settings are not read
   here. min-height guards the case where the panel is taller than the photo's own ratio
   would allow, so it can never hang past the bottom edge. */
.psw-feed-featured-cardover {
	position: relative;
	display: block;
	/* Height comes from .psw-feed-featured, the same as Standard and Overlay. This used to
	   be aspect-ratio: 3/1 with a 300px floor, which made Cardover the only mode whose
	   height moved with the page width — 400px at a 1200px content width against the other
	   two at 370px. The panel is capped and scrolls, so it cannot hang past the edge
	   without the old min-height. */
	overflow: hidden;
	border-radius: var(--psw-radius-cards);
}
.psw-cardover-bg {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	display: block;
	line-height: 0;
}
.psw-cardover-bg img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	border-radius: 0 !important;
}
.psw-cardover-panel {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	right: 24px;
	width: 33%;
	max-height: calc(100% - 32px);
	overflow: auto;
	box-sizing: border-box;
	padding: var(--psw-card-padding, 14px);
	background: var(--psw-color-card-bg);
	border-radius: var(--psw-radius-cards);
	/* The panel is the thing that floats: it sits over the photograph, so a little depth
	   separates it from what is behind it. On the card as a whole the same shadow did
	   nothing useful — that edge is against the page, not against an image. */
	box-shadow: 0 2px 10px rgba(0, 0, 0, .08);
}
/* The panel flips to the left of the banner in RTL, matching how the Standard featured
   post already reverses its two columns. */
.psw-rtl .psw-feed-featured-cardover .psw-cardover-panel,
.psw-feed-featured-cardover.psw-rtl .psw-cardover-panel {
	right: auto;
	left: 24px;
}
.psw-feed-featured-cardover .psw-cardover-panel h3 { margin: 6px 0 8px; }
.psw-feed-featured-cardover .psw-cardover-panel .psw-feed-footer { margin-top: 10px; }
@media (max-width: 780px) {
	/* On a phone a third-width panel is unreadable, so it spans the banner and anchors to
	   the bottom, inset on three sides — the arrangement in the mobile mock. */
	.psw-feed-featured-cardover {
		/* height:auto is needed here now that the desktop rule no longer sets it: without
		   it the fixed height inherited from .psw-feed-featured would win over the ratio
		   between 640px and 780px, and the square mobile layout would not appear. */
		height: auto;
		aspect-ratio: 1 / 1;
		min-height: 0;
	}
	.psw-feed-featured-cardover .psw-cardover-panel,
	.psw-rtl .psw-feed-featured-cardover .psw-cardover-panel,
	.psw-feed-featured-cardover.psw-rtl .psw-cardover-panel {
		top: auto;
		transform: none;
		left: 16px;
		right: 16px;
		bottom: 16px;
		width: auto;
		max-height: calc(100% - 32px);
		/* Reads the setting like every other card. A fixed value here beat the token on a
		   phone specifically — higher specificity, inside the mobile query — so the mobile
		   padding setting had no effect on this panel however it was set. */
		padding: var(--psw-card-padding, 14px);
	}
}

/* Single post: previous / next navigation. Deliberately plain — it sits inside whatever
   the theme renders for a post, so it announces itself with structure rather than colour. */
.psw-post-nav {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
	margin: 32px 0;
	padding-top: 16px;
	border-top: 1px solid var(--psw-border-form-color, #eee);
}
.psw-post-nav-side a {
	display: flex;
	flex-direction: column;
	gap: 4px;
	text-decoration: none;
	color: inherit;
}
.psw-post-nav-next { text-align: right; }
.psw-post-nav-label {
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--psw-color-muted);
}
.psw-post-nav-title { font-size: 15px; }
.psw-post-nav-side a:hover .psw-post-nav-title { text-decoration: underline; }

/* Related posts. Its own compact layout rather than the feed card styles — a full feed
   card carries meta rows, publisher and action buttons that only make sense in a feed.
   The column count comes from the shortcode via a custom property. */
.psw-related { margin: 32px 0; }
.psw-related-title { font-size: 18px; margin: 0 0 16px; }
.psw-related-grid {
	display: grid;
	grid-template-columns: repeat(var(--psw-related-columns, 3), 1fr);
	gap: 20px;
}
.psw-related-card {
	display: flex;
	flex-direction: column;
	gap: 8px;
	text-decoration: none;
	color: inherit;
	min-width: 0;
}
.psw-related-card-img {
	display: block;
	overflow: hidden;
	border-radius: var(--psw-radius-cards, 6px);
	aspect-ratio: 16 / 9;
}
.psw-related-card-img img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.psw-related-card-title { font-size: 14px; line-height: 1.4; }
.psw-related-card:hover .psw-related-card-title { text-decoration: underline; }
@media (max-width: 900px) {
	.psw-related-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
	/* One column below this width — a 16:9 thumbnail in a half-width phone column is
	   too small to tell anything apart. */
	.psw-related-grid { grid-template-columns: 1fr; }
	.psw-post-nav { grid-template-columns: 1fr; }
	.psw-post-nav-next { text-align: left; }
}

/* Info Post Image Side. Order, not a reversed row: the right-to-left class already reverses
   this row, and two reversals cancel out — an RTL post would have put the picture back where
   it started. Order stacks with that instead, so an RTL post mirrors the sides. */
.psw-feed-featured-infopost.psw-infopost-img-right .psw-feed-featured-img { order: 2; }
.psw-feed-featured-infopost.psw-infopost-img-right .psw-feed-featured-body { order: 1; }

/* ------------------------------------------------------------------------- Animation */

/* Nothing is hidden until the script says so. .psw-anim-ready is added by JavaScript, so a
   browser that never runs it — or a page where the script fails — shows the cards normally
   rather than showing nothing at all. That is the whole reason the class exists. */
.psw-anim-ready.psw-anim-fade .psw-feed-card,
.psw-anim-ready.psw-anim-fade .psw-feed-featured,
.psw-anim-ready.psw-anim-fade .psw-archive-row,
.psw-anim-ready.psw-anim-both .psw-feed-card,
.psw-anim-ready.psw-anim-both .psw-feed-featured,
.psw-anim-ready.psw-anim-both .psw-archive-row {
	opacity: 0;
	transform: translateY(44px);
	/*
	 * Slower, so the arrival is something you watch rather than something that has already
	 * happened by the time you look. Three quarters of a second read as a snap at the speed
	 * most people scroll, and even a second and a fifth was gone before it registered. The easing is unchanged, so it still settles rather than stopping.
	 */
	transition: opacity 2.6s ease, transform 2.6s cubic-bezier(.22, .61, .36, 1);
	will-change: opacity, transform;
}
.psw-anim-ready .psw-anim-in {
	opacity: 1 !important;
	transform: none !important;
}

/* The frame clips. Without this the scaled picture simply overflowed and pushed into the
   text beneath it — which reads as the card data overlapping the image, and means the drift
   never looked like parallax because nothing was holding the picture still around it.
   A fixed height too: a wrapper that sizes itself to its content grows with the scaled
   picture, so there would still be nothing to move within. */
.psw-anim-ready.psw-anim-parallax .psw-card-img-wrap,
.psw-anim-ready.psw-anim-parallax .psw-feed-featured-img,
.psw-anim-ready.psw-anim-both .psw-card-img-wrap,
.psw-anim-ready.psw-anim-both .psw-feed-featured-img {
	/* No radius here at all.
	   The card already has both a radius and overflow: hidden, so it clips its own contents
	   to the rounded shape — the corners are its job and always were. This wrapper only
	   needs to stop a scaled picture spilling into the text below it.
	   Two wrong answers preceded this one: the card radius, which rounded all four corners
	   of a picture that sits at the top of a card, and inherit, which copies that same
	   all-four-corners value from the card and so was the identical mistake spelled
	   differently. */
	overflow: hidden;
}

/* The picture drifts against the scroll. Scale first, so the movement has somewhere to go:
   translating an image that exactly fills its frame drags an empty edge into view. */
/* .psw-card-img-wrap img, not .psw-feed-card-img img. The wrapper is emitted by the shared
   renderer for every card in every style; the class inside it is passed in per style, so
   keying off that reached some styles and not others — and cards that were simply never
   selected look exactly like parallax being broken. */
.psw-anim-ready.psw-anim-parallax .psw-card-img-wrap img,
.psw-anim-ready.psw-anim-parallax .psw-feed-featured-img img,
.psw-anim-ready.psw-anim-parallax .psw-overlay-bg img,
.psw-anim-ready.psw-anim-parallax .psw-cardover-bg img,
.psw-anim-ready.psw-anim-both .psw-card-img-wrap img,
.psw-anim-ready.psw-anim-both .psw-feed-featured-img img,
.psw-anim-ready.psw-anim-both .psw-overlay-bg img,
.psw-anim-ready.psw-anim-both .psw-cardover-bg img {
	/*
	 * How far the picture is enlarged, and therefore how far it can travel.
	 *
	 * A parallax drift is the picture moving inside a frame that clips it. The only room it
	 * has to move is what the scale puts outside the frame, so intensity and scale are the
	 * same number: at 1.45 there was 22.5% of the height hidden on each side and the drift
	 * could never be more than that.
	 *
	 * Stated as a variable because the script that does the moving has to know it. Written
	 * in two places it would drift out of step, and the symptom of that is the ugly one —
	 * the picture sliding past its own edge and showing the card through the gap.
	 */
	--psw-parallax-scale: 1.7;
	transform: scale(var(--psw-parallax-scale, 1.7));
	will-change: transform;
}

/* Anyone whose system asks for less movement gets none, whatever the setting says. This is
   not a preference to weigh against the site's — it is a statement that motion causes some
   people physical symptoms. */
@media (prefers-reduced-motion: reduce) {
	.psw-anim-ready.psw-anim-fade .psw-feed-card,
	.psw-anim-ready.psw-anim-fade .psw-feed-featured,
	.psw-anim-ready.psw-anim-fade .psw-archive-row,
	.psw-anim-ready.psw-anim-both .psw-feed-card,
	.psw-anim-ready.psw-anim-both .psw-feed-featured,
	.psw-anim-ready.psw-anim-both .psw-archive-row {
		opacity: 1;
		transform: none;
		transition: none;
	}
	.psw-anim-ready.psw-anim-parallax .psw-card-img-wrap img,
	.psw-anim-ready.psw-anim-parallax .psw-feed-featured-img img,
	.psw-anim-ready.psw-anim-parallax .psw-overlay-bg img,
	.psw-anim-ready.psw-anim-parallax .psw-cardover-bg img,
	.psw-anim-ready.psw-anim-both .psw-card-img-wrap img,
	.psw-anim-ready.psw-anim-both .psw-feed-featured-img img,
	.psw-anim-ready.psw-anim-both .psw-overlay-bg img,
	.psw-anim-ready.psw-anim-both .psw-cardover-bg img {
		transform: none;
	}
}

/* The Info Post ratio frame, when one is set. The frame itself carries its shape inline —
   see the renderer for why — and these only make the chain inside it fill the frame.
   Nothing here decides the shape, so nothing here can disagree with it. */
/* Also printed inline on every page load — see the settings class. Kept here as well so
   the file remains readable on its own; whichever arrives, they say the same thing. */
.psw-infopost-frame .psw-infopost-fill,
.psw-infopost-frame .psw-infopost-fill .psw-card-img-wrap,
.psw-infopost-frame .psw-infopost-fill a {
	display: block;
	width: 100%;
	height: 100%;
	max-height: none;
	border-radius: 0;
}
.psw-infopost-frame .psw-infopost-fill img {
	width: 100%;
	height: 100%;
	/* Releasing max-height as well as setting height: the stacked mobile layout caps a
	   featured picture at 220px, and a cap beats a percentage height. */
	max-height: none;
	max-width: none;
	min-height: 0;
	object-fit: cover;
	display: block;
	aspect-ratio: auto;
}

/*
 * Last in the file on purpose.
 *
 * Everything above states how a featured card looks on a desk, and several of those rules
 * name the same number of classes as these do. Written earlier, as this was, they lost the
 * tie and a phone kept the desktop answer — which is why the picture would not take the
 * height it was given here.
 */
/*
 * A featured card on a phone, every style, stated once.
 *
 * This was two blocks at two widths with overlapping fragments, and each repair to one of
 * them broke the other. It is written out here in full instead: what the card is, what the
 * picture column is, and what the picture does — no rule relying on a value another rule
 * happens to leave behind.
 *
 * 780, not 640, so a card stacks at the same width whichever style it is. They disagreed
 * before, and between the two numbers a standard card was still in two columns while an
 * Info Post had already stacked.
 */
@media (max-width: 780px) {
	/*
	 * Stacked and sized by its contents.
	 *
	 * The :not chain is repeated from the rule that states the height. Four classes there,
	 * and anything shorter here loses to it — which is exactly how a card came to sit 370px
	 * tall on a phone with its picture above its text and no room for either.
	 */
	.psw-feed-featured,
	.psw-feed-featured:not(.psw-feed-featured-overlay):not(.psw-feed-featured-cardover):not(.psw-bio-header),
	.psw-feed-featured-infopost {
		flex-direction: column;
		height: auto;
		min-height: 0;
		align-items: stretch;
	}

	/*
	 * Overlay and Cardover are the exception, and deliberately.
	 *
	 * Everything inside them is absolutely positioned — photo, meta row, text, footer — so
	 * with no height and nothing in normal flow they collapse to nothing and the post
	 * disappears. A square is what they take instead.
	 */
	.psw-feed-featured-overlay,
	.psw-feed-featured-cardover {
		height: auto;
		aspect-ratio: 1 / 1;
		min-height: 0;
	}

	/* The picture column: full width, and a height of its own. */
	.psw-feed-featured-img,
	.psw-feed-featured-infopost .psw-feed-featured-img,
	/* The ratio frame is named too. It carries three classes and would otherwise keep its
	   own answer here, since it is written at every width. */
	.psw-image-ratio .psw-feed-featured-infopost .psw-feed-featured-img {
		flex: 0 0 auto;
		width: 100%;
		max-width: 100%;
		height: 220px;
		min-height: 0;
	}

	/*
	 * And every box between that column and the picture takes all of it.
	 *
	 * A percentage of a box that sized itself to its contents is auto again, so one missing
	 * link here is enough for the picture to go back to choosing its own height — which is
	 * what a tall portrait did, taking half the screen.
	 */
	.psw-feed-featured-img .psw-card-img-wrap,
	.psw-feed-featured-img a {
		height: 100%;
	}

	.psw-feed-featured-img img {
		width: 100%;
		height: 100%;
		min-height: 0;
		max-height: none;
		object-fit: cover;
	}

	/*
	 * The picture comes first, whichever side it takes on a desk.
	 *
	 * Image Side is about two columns side by side. Stacked there are no sides, and the
	 * order it sets was still being obeyed — so choosing Right on a desktop put the picture
	 * under the text on a phone, which is not what that setting means.
	 */
	.psw-feed-featured-infopost .psw-feed-featured-img,
	.psw-feed-featured-infopost.psw-infopost-img-right .psw-feed-featured-img {
		order: 0;
	}

	.psw-feed-featured-infopost .psw-feed-featured-body,
	.psw-feed-featured-infopost.psw-infopost-img-right .psw-feed-featured-body {
		order: 1;
	}
}

/* The archive on a phone: stacked, picture first, capped — the same arrangement every
   featured card takes there, for the same reason. */
@media (max-width: 780px) {
	.psw-archive-row,
	.psw-archive-row.psw-rtl {
		flex-direction: column;
	}

	.psw-archive-row-img {
		flex: 0 0 auto;
		width: 100%;
		max-width: 100%;
		height: 200px;
	}
}

/* One column on a phone, with the way in at the top where it can be reached without
   scrolling past the history to find it. */
@media (max-width: 780px) {
	.psw-archive-shell {
		grid-template-columns: minmax(0, 1fr);
		gap: 30px;
	}

	.psw-archive-index {
		order: -1;
		position: static;
		margin-top: 0;
	}

	/*
	 * The gap under the navigation, made up to the same thirty.
	 *
	 * The bar is not inside the archive — it is printed before it, by the navigation — so it
	 * cannot be reached from here by name, and its own bottom margin is twenty-two. This
	 * adds the remaining eight rather than fighting for the bar's margin, which belongs to
	 * every screen and not only this one.
	 */
	.psw-wrap.psw-archive { margin-top: 8px; }

	/*
	 * One measure between everything above the history: the navigation, the search row, the
	 * panel, and the first period's heading. They were four different gaps, each inherited
	 * from whatever the element happened to be.
	 */
	.psw-archive .psw-feed-search { margin-bottom: 30px; }
	.psw-archive-period-head { margin-bottom: 30px; }
	.psw-archive-period + .psw-archive-period { margin-top: 30px; }

	/* Folded, with the arrow that says so. */
	.psw-archive-index-fold > summary {
		display: flex;
		flex-direction: column;
		gap: 6px;
		cursor: pointer;
		list-style: none;
	}

	.psw-archive-index-fold > summary::-webkit-details-marker { display: none; }

	.psw-archive-index-title {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 8px;
	}

	/* The arrow, drawn in text so it takes the colour around it and needs no file. It turns
	   when the list is open, which is the whole of its job. */
	.psw-archive-index-title::after {
		content: "";
		width: 7px;
		height: 7px;
		border-right: 1.5px solid currentColor;
		border-bottom: 1.5px solid currentColor;
		transform: rotate(45deg) translate(-2px, -2px);
		transition: transform 0.15s;
	}

	.psw-archive-index-fold[open] .psw-archive-index-title::after {
		transform: rotate(225deg) translate(-2px, -2px);
	}

	.psw-archive-index-fold:not([open]) > ul { display: none; }
}
